Linux Kernel 中断子系统

Linux 将中断处理流程划分成两个部分,一个是top half,另一个是bottom half。

在执行top half时是关闭硬件中断的,即系统没办法响应后续的中断事件,因此应该保证top half尽可能短。

把不那么紧急的事情defer到bottom half去做。

#bottom half

bottom half有多个实现机制

  • BH 最早的实现,已经弃用了

  • Task queue 已经弃用了

  • Softirq 运行在 interrupt context top half中raise_softirq(nr),每个cpu串行执行

  • tasklet 运行在 interrupt context

  • workqueue 运行在 process context

#Softirq

softirq和hardirq(硬件中断)对应,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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有三个处理时机

  1. 中断上下文 irq_exit() 的时候
  2. 任意 local_bh_enable()
  3. softirqd 内核线程定期执行

#tasklet

per-cpu会有一个tasklet的链表

1
2
static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);
static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);