软中断
软中断(softirq)是中断处理程序在开启中断的情况下执行的部分,可以被硬中断抢占。
内核定义了一张软中断向量表,每种软中断有一个唯一的编号,对应一个softirq_action实例,softirq_action实例的成员action是处理函数。
kernel/softirq.c
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; /* 软中断向量表 */
include/linux/interrupt.h
struct softirq_action
{
void (*action)(struct softirq_action *); /* 软中断处理函数 */
};
1. 软中断的种类
目前内核定义了10种软中断,定义如下:
include/linux/interrupt.h
enum
{
HI_SOFTIRQ=0, /* 高优先级的小任务 */
TIMER_SOFTIRQ, /* 定时器软中断 */
NET_TX_SOFTIRQ, /* 网络栈发送报文的软中断 */
NET_RX_SOFTIRQ, /* 网络栈接收报文的软中断 */
BLOCK_SOFTIRQ, /* 块设备软中断 */
IRQ_POLL_SOFTIRQ, /* 支持IO轮询的块设备软中断 */
TASKLET_SOFTIRQ, /* 低优先级的小任务 */
SCHED_SOFTIRQ, /* 调度软中断,用于在处理器之间的负载均衡 */
HRTIMER_SOFTIRQ, /* 高精度定时器 */
RCU_SOFTIRQ, /* RCU软中断 */
NR_SOFTIRQS
};
软中断的编号越小优先级越高。
2. 注册软中断的处理函数
函数open_softirq()用来注册软中断的处理函数,在软中断向量表中为指定的软终端编号设置处理函数。
kernel/softirq.c
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
softirq_vec[nr].action = action;
}
同一种软中断的处理函数可以在多个处理器上同时执行,处理函数必须是可以重入的,需要使用锁保护临界区。
3. 触发软中断
函数raise_softirq用来触发软中断,参数是软中断编号。
void raise_softirq(unsigned int nr);
在已经禁止中断的情况下可以调用函数raise_softirq_irqoff来触发中断。
void raise_softirq_irqoff(unsigned int nr);
函数raise_softirq在当前处理器的待处理软中断位图中为指定的软中断编号设置对应的位,如下所示:
raise_softirq() -> raise_softirq_irqoff() -> __raise_softirq_irqoff()
kernel/softirq.c
void __raise_softirq_irqoff(unsigned i

本文深入解析Linux内核中的软中断机制,包括软中断的种类、注册处理函数、触发与执行流程,以及与抢占计数器的关系。软中断是内核处理异步事件的重要手段,了解其工作原理对于系统优化至关重要。
最低0.47元/天 解锁文章
719





