歡迎轉載,轉載時需保留做者信息,謝謝。web
郵箱:tangzhongp@163.com數組
博客園地址:http://www.cnblogs.com/embedded-tzp數據結構
Csdn博客地址:http://blog.csdn.net/xiayulewa函數
早看到這篇文章,就不寫了,懶:spa
Linux中斷(interrupt)子系統之五:軟件中斷(softIRQ): http://blog.csdn.net/droidphone/article/details/7518428.net
struct softirq_action線程
{rest
void (*action)(struct softirq_action *);orm
};blog
² static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
softirq_vec是一個struct softirq_action數組,使用open_softirq註冊
Softirq.c (src\kernel):52 中:
² irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
其操做:raise_softirq_irqoff→or_softirq_pending置位bitmap:irq_stat[cpu].__softirq_pending
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
softirq_vec[nr].action = action;
}
不是鏈表結構。
可被註冊的有
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
如在softirq_init中有open_softirq(TASKLET_SOFTIRQ, tasklet_action);
這說明 tasklet是被放入軟中斷中執行的。
open_softirq註冊→raise_softirq→raise_softirq_irqoff→raise_softirq_irqoff→wakeup_softirqd
在wakeup_softirqd中喚醒ksoftirqd進程,
static struct smp_hotplug_thread softirq_threads = {
.store = &ksoftirqd,
.thread_should_run = ksoftirqd_should_run,
.thread_fn = run_ksoftirqd,
.thread_comm = "ksoftirqd/%u",
};
執行.thread_fn = run_ksoftirqd →__do_softirq
在 _do_softirq中有
h = softirq_vec;
……………………………
h->action(h); 即爲具體註冊函數
……………………………
Ksoftirqd:是個線程, 其流程爲
start_kernel→rest_init→kernel_init→kernel_init_freeable
→do_basic_setup→do_initcalls→spawn_ksoftirqd
→smpboot_register_percpu_thread(&softirq_threads)
open_softirq註冊→raise_softirq→raise_softirq_irqoff→raise_softirq_irqoff→irq_exit(在中斷退出時執行)→invoke_softirq→do_softirq(或wakeup_softirqd) →__do_softirq→ h->action(h); 即爲具體註冊函數