softirq
Linux Kernel 中的 softirq(软件中断)机制是中断处理的下半部分(bottom half)的一种实现形式,用于延迟处理部分中断任务,以减少中断禁用时间、提高系统响应能力
SoftIRQ 的设计动机
中断处理通常分为:
- Top Half:快速响应中断,执行最小必要的操作。
- Bottom Half:执行耗时操作(如协议栈处理、数据拷贝)。
为了避免长时间禁用中断,Linux 提供了几种 bottom half 实现机制:
| 机制 | 描述 | 使用场景 |
|---|---|---|
| softirq | 静态分配、快速、非抢占 | 网络、块设备等 |
| tasklet | 基于 softirq、动态调度 | 驱动私有 bottom half |
| workqueue | 基于线程、可阻塞 | 复杂、需要睡眠操作 |
SoftIRQ 的关键数据结构
softirq_vec
struct softirq_action {
void (*action)(struct softirq_action *);
};
每种 softirq 类型有一个对应的处理函数。
SoftIRQ 编号
内核定义了最多 10 个 softirq 类型(在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,
RCU_SOFTIRQ,
NR_SOFTIRQS
};
SoftIRQ 的注册与触发
注册处理函数
在内核初始化阶段,softirq 处理函数通过 open_softirq() 注册:
void open_softirq(int nr, void (*action)(struct softirq_action *))
例如网络子系统注册:open_softirq(NET_RX_SOFTIRQ, net_rx_action);
激活 softirq
使用 raise_softirq():
void raise_softirq(unsigned int nr)
本质上是设置当前 CPU 的 pending 标志位。
SoftIRQ 的调度执行机制
SoftIRQ 的调度由以下路径触发:
- 中断返回路径:从硬件中断处理函数返回时,检查 pending softirq。
- 时钟中断定时检查。
- 显式调用:
local_bh_enable()或do_softirq()触发。
do_softirq() > __do_softirq()
核心逻辑:
pending = local_softirq_pending();
for_each_set_bit(i, &pending) {
softirq_vec[i].action(&softirq_vec[i]);
}
SoftIRQ 的局限性
- 不能睡眠:执行在中断上下文,不允许阻塞。
- 无抢占:直到所有 pending softirq 执行完才能退出。
- CPU 绑定:在触发 softirq 的 CPU 上执行,不能迁移。
- 可能导致长时间占用 CPU:尤其在网络高负载时。
SoftIRQ 的实际用途
| SoftIRQ 类型 | 主要用途 |
|---|---|
NET_RX_SOFTIRQ | 网络接收处理 |
NET_TX_SOFTIRQ | 网络发送完成处理 |
BLOCK_SOFTIRQ | 块设备 I/O 处理 |
RCU_SOFTIRQ | RCU 回调执行 |
TIMER_SOFTIRQ | 定时器触发 |
TASKLET_SOFTIRQ | tasklet 支持 |
总结
| 优点 | 缺点 |
|---|---|
| 高性能、低延迟 | 不能阻塞、不可抢占 |
| 多核独立处理 | 不易管理、调试困难 |
SoftIRQ 是内核性能优化的重要手段,尤其适用于 网络协议栈、定时器、RCU 回调等高频场景。理解其机制对分析系统瓶颈、驱动优化非常关键。
5542

被折叠的 条评论
为什么被折叠?



