1. 中断基础:什么是中断、硬中断与软中断的区别、中断向量表与IDT
1.1 什么是中断
中断(Interrupt)是计算机体系结构中一种核心的异步事件处理机制。它允许硬件设备(如网卡、磁盘、键盘)或软件指令(如系统调用)在任意时刻通知CPU,暂停当前正在执行的程序流,转而去执行一个优先级更高的中断处理程序(Interrupt Service Routine, ISR)。
从系统架构视角看,中断解决了CPU与外部设备之间速度不匹配的问题。没有中断,CPU必须通过轮询(Polling)不断检查设备状态,这会浪费大量CPU周期。中断机制让CPU在无事可做时执行低优先级任务或进入低功耗状态,仅在设备需要服务时才被唤醒。
1.2 硬中断与软中断的区别
Linux内核将中断处理分为两个阶段:硬中断(Hard IRQ)和软中断(SoftIRQ)。这种拆分是为了平衡“快速响应”与“复杂处理”之间的矛盾。
| 特性 | 硬中断(Hard IRQ) | 软中断(SoftIRQ) |
|---|---|---|
| 触发源 | 硬件设备(网卡、磁盘、定时器) | 内核代码自身(硬中断下半部、ksoftirqd) |
| 执行上下文 | 中断上下文(不可睡眠、不可调度) | 中断上下文或进程上下文(ksoftirqd) |
| 执行优先级 | 最高,会抢占所有进程和其他软中断 | 高于普通进程,低于硬中断 |
| 执行时间要求 | 极短(微秒级),只做最必要的操作 | 相对宽松(毫秒级),可处理复杂逻辑 |
| 典型操作 | 保存寄存器、应答设备、触发软中断 | 网络协议栈处理、定时器回调、任务调度 |
| 可中断性 | 不可被其他硬中断打断(除非嵌套中断开启) | 可被硬中断打断 |
1.3 中断向量表与IDT
中断向量表(Interrupt Vector Table, IVT)是CPU用来查找中断处理程序入口地址的数据结构。在x86架构的实模式下,IVT位于内存地址0x0000~0x03FF,共256个条目,每个条目4字节,包含段地址和偏移量。
进入保护模式后,IVT被更强大的中断描述符表(Interrupt Descriptor Table, IDT)取代。IDT可以位于内存任意位置,通过IDTR寄存器定位。每个IDT条目(门描述符)大小为8字节,包含中断处理程序的段选择子、偏移量、特权级(DPL)和类型(中断门/陷阱门/任务门)。
1.4 中断向量分配与常见中断号
在x86架构中,256个中断向量有明确的分配规则:
- 0~31:保留给CPU异常和陷阱(如#DE除零异常、#PF页故障、#BP断点陷阱)。这些由CPU内部触发,不是硬件中断。
- 32~47(IRQ 0~15):传统PIC(8259A)的中断号范围。IRQ 0是定时器,IRQ 1是键盘,IRQ 3/4是串口。
- 48~255:用于APIC(高级可编程中断控制器)的中断号,以及系统调用(Linux使用0x80或sysenter)。
1.5 中断亲缘性(IRQ Affinity)基础
中断亲缘性是指将特定中断号的中断处理限制在指定的CPU核心或核心组上执行。Linux通过/proc/irq/{IRQ_NUM}/smp_affinity文件暴露此控制接口,该文件存储一个十六进制位图(bitmask),每一位代表一个CPU核心。
# 查看中断号 78 的当前亲缘性
cat /proc/irq/78/smp_affinity
00000000,00000000,00000000,00000001
# 将中断 78 绑定到 CPU 0 和 CPU 2(位图:bit0=1, bit2=1 → 0x05)
echo 05 > /proc/irq/78/smp_affinity
# 使用 chcpu 或 irqbalance 服务进行动态管理
systemctl status irqbalance
在NUMA架构服务器上,错误的中断亲缘性配置会导致跨内存域访问(Remote Memory Access),显著增加延迟。网卡多队列调优的核心目标之一,就是确保每个队列的中断及其后续软中断处理都在同一NUMA节点上的CPU核心完成。