3. 中断基础概念:硬中断与软中断的区别、中断向量表、中断处理流程
在深入软中断亲和性调优之前,必须彻底理解中断的底层机制。中断是CPU与外部设备交互的核心事件驱动方式,而硬中断(Hard IRQ)与软中断(SoftIRQ)的分工协作,直接决定了多核网络负载均衡的成败。本节将拆解中断向量表、硬中断处理流程以及软中断的触发与执行。
3.1 硬中断(Hard IRQ)与软中断(SoftIRQ)的本质区别
硬中断由硬件设备(如网卡、磁盘控制器)通过中断控制器(如APIC)向CPU发送电信号触发;软中断则由内核软件在特定时机(如硬中断处理完成后)主动触发,用于处理耗时但非紧急的下半部任务。
| 对比维度 | 硬中断(Hard IRQ) | 软中断(SoftIRQ) |
|---|---|---|
| 触发源 | 硬件设备(网卡、磁盘、定时器) | 内核软件(硬中断处理函数、ksoftirqd) |
| 执行上下文 | 中断上下文(不可睡眠、不可调度) | 中断上下文或进程上下文(ksoftirqd) |
| 执行优先级 | 最高(可抢占进程、可嵌套) | 次高(低于硬中断,高于普通进程) |
| 耗时要求 | 必须极短(微秒级),否则丢包 | 可稍长(毫秒级),但需避免饥饿 |
| 中断号分配 | 由中断控制器分配(0~255) | 内核静态枚举(如NET_RX_SOFTIRQ) |
| 亲和性控制 | /proc/irq/<N>/smp_affinity |
/proc/irq/<N>/smp_affinity + 内核参数 |
调优关键认知: 网卡收包时,硬中断仅完成“数据从硬件DMA到内存”的极简操作,而协议栈解析、路由查找、socket交付等重头戏全部在软中断中完成。因此,软中断的CPU亲和性配置才是网络负载均衡的核心战场。
3.2 中断向量表(Interrupt Vector Table, IVT)
中断向量表是CPU在实模式或保护模式下用于查找中断处理程序入口地址的跳转表。在x86_64 Linux系统中,中断向量表由IDT(Interrupt Descriptor Table)实现,每个中断向量对应一个门描述符(Gate Descriptor),包含段选择子、偏移地址、DPL(特权级)和类型(中断门/陷阱门)。
关键事实: 在Linux中,
0x00~0x1F 为CPU异常和陷阱向量(如缺页 #PF、除零 #DE),0x20~0xFF 为硬件中断向量(IRQ)。网卡中断通常映射到 0x20 之后的某个向量,具体编号由IOAPIC分配。
3.3 中断处理流程:从硬件信号到软中断执行
一次完整的网络中断处理分为上半部(硬中断)和下半部(软中断)两个阶段。上半部必须快速完成,下半部可以延迟处理。
3.4 硬中断处理函数的关键约束
- 不可睡眠: 中断上下文没有进程调度实体,调用
schedule()或wait_event()会导致内核崩溃。 - 不可持有普通锁: 只能使用
spin_lock()等自旋锁,不能使用mutex_lock()。 - 必须极短: 典型硬中断处理时间应 < 10μs,否则会阻塞其他中断或导致网络RX ring buffer溢出。
- 典型操作: 读取设备状态寄存器、清除中断标志、将skb加入队列、触发软中断。
3.5 软中断的执行时机与ksoftirqd
软中断在以下三种时机被检查并执行:
- 硬中断返回前: 在
do_IRQ()末尾调用irq_exit()→invoke_softirq()。 - 高优先级软中断主动唤醒: 如
raise_softirq()在硬中断中调用。 - ksoftirqd 内核线程: 当软中断执行时间过长或负载过高时,内核唤醒每个CPU上的
ksoftirqd/N线程(N为CPU编号)在进程上下文中处理剩余软中断。
性能陷阱: 如果软中断在硬中断返回前执行(即
do_softirq() 直接执行),它仍然运行在中断上下文中,此时不能睡眠、不能调度。只有当软中断被推迟到 ksoftirqd 执行时,才处于进程上下文,可以睡眠。网络软中断通常直接在硬中断返回前执行,因此必须保持高效。
3.6 中断亲和性(IRQ Affinity)的配置基础
中断亲和性决定了哪个CPU核心处理特定的硬中断。通过修改 /proc/irq/<IRQ_NUMBER>/smp_affinity 文件,可以指定允许处理该中断的CPU位图。
# 查看网卡中断号(以 eth0 为例)
cat /proc/interrupts | grep eth0
# 输出示例:
# CPU0 CPU1 CPU2 CPU3
# 32: 12345 67890 11111 22222 IR-PCI-MSI eth0
# 将中断号32的亲和性设置为仅CPU2和CPU3(位图:1100 = 0x0C)
echo 0x0C > /proc/irq/32/smp_affinity
# 查看当前亲和性掩码
cat /proc/irq/32/smp_affinity
# 输出:00000000,0000000c
重要提示: 硬中断亲和性设置后,软中断默认继承硬中断的CPU亲和性。但现代内核允许通过
/proc/irq/<N>/smp_affinity_list 或 irqbalance 服务进行更精细的软中断分发。后续章节将深入讲解如何利用RPS/RFS/XPS等技术实现软中断的跨核负载均衡。
3.7 本章小结:中断基础与调优的关联
| 基础概念 | 与软中断亲和性调优的直接关联 |
|---|---|
| 硬中断 vs 软中断 | 软中断是网络协议栈处理的主战场,其CPU亲和性决定吞吐量 |
| 中断向量表(IDT) | 每个硬件中断对应唯一向量,亲和性配置基于中断号 |
| 硬中断处理流程 | 硬中断必须极短,否则导致丢包;软中断可延迟但需避免饥饿 |
| ksoftirqd 线程 | 当软中断负载过高时,ksoftirqd 成为调优对象(优先级、CPU绑定) |
| smp_affinity 位图 | 直接控制硬中断和软中断的CPU分布,是负载均衡的起点 |