对于中断处理而言,linux将其分成了两个部分, 一个叫做中断handler(top half), 是全程关闭中断的, 主要处理中断的一些实时性任务, 另外一部分是deferable task(bottom half), 处理不那么紧急需要处理的事情。在执行bottom half的时候,是开中断的。bottom half的机制主要有softirq, tasklet和workqueue, 这三者有本质的区别:workqueue运行在process context,而softirq和tasklet运行在interrupt context.
softirq和hardirq是相对应的一个概念, 因此可以依据hardirq的机制来理解softirq, 不过softirq是一个纯软件的概念, 不需要任何硬件来参与, 故而没有和硬件相关的一些概念.比如hwirq id, irq_chip等等.
1.softirq number
softirq number是和hard irq中逻辑中断号相对应的一个概念, 用来标示一个softirq. 具体的softirq number定义如下:
路径: include/linux/interrupt.h
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
IRQ_POLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the
numbering. Sigh! */
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
softirq number是静态分配的, 这一点和hardirq 逻辑中断号的动态映射不同.
- HI_SOFTIRQ 用于高优先级的tasklet.
- TIMER_SOFTIRQ 用于software timer.
- TASKLET_SOFTIRQ 用于低优先级的tasklet.
2.what is softirq desc
和hardirq一样, softirq也存在软中断描述符.相对于hardirq desc, softirq desc相当简单, 只有一个callback 函数. 具体如下:
路径: include/linux/interrupt.h
struct softirq_action
{
void (*action)(struct softirq_action *);
};
路径: kernel/softirq.c
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
内核为每一个softirq定义了一个softirq_action结构, 用一个静态分配的结构体结构体数组softirq_vec来表示, 实现了softirq number和softirq desc的关联. 如果触发了某个softirq就调用相应的callback函数.
3.what is softirq register
由于softirq是一个纯软件的概念, 当触发了一个softirq时, 也需要一个"register"来记录该事件发生了, 以便在将来的某个时候可以调用某个处理函数. 在