【linux kernel】 softirq 軟中斷討論

歡迎轉載,轉載時需保留做者信息,謝謝。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

1.1.  數據結構

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置位bitmapirq_stat[cpu].__softirq_pending

 

1.2.  軟中斷註冊

 

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是被放入軟中斷中執行的。

1.3.  軟中斷執行流程

1.3.1.   路徑1

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_kernelrest_initkernel_initkernel_init_freeable

do_basic_setup→do_initcalls→spawn_ksoftirqd

→smpboot_register_percpu_thread(&softirq_threads)

 

 

1.3.2.   路徑2

open_softirq註冊→raise_softirq→raise_softirq_irqoff→raise_softirq_irqoff→irq_exit(在中斷退出時執行)→invoke_softirq→do_softirq(wakeup_softirqd) →__do_softirq→ h->action(h); 即爲具體註冊函數

相關文章
相關標籤/搜索