4. Linux 中断子系统基础:IRQ编号、中断描述符、中断控制器

在配置软中断CPU亲和性之前,必须理解Linux内核如何管理硬件中断。中断子系统是协议栈收包的“第一入口”,其核心组件包括IRQ编号、中断描述符和中断控制器。这三者构成了从硬件设备到内核处理函数的完整链路。

核心概念:IRQ编号是中断的“身份证”,中断描述符是中断的“档案袋”,中断控制器是中断的“交通警察”。三者协同工作,确保每个硬件中断都能被正确路由到目标CPU。

4.1 IRQ编号:中断的唯一标识

IRQ(Interrupt ReQuest)编号是Linux内核为每个中断源分配的全局唯一整数标识符。它分为两种类型:

  • 硬件IRQ编号(hwirq):由中断控制器硬件定义的原始编号,与具体平台相关。
  • Linux IRQ编号(irq):内核软件层使用的逻辑编号,与平台无关,用户空间通过/proc/interrupts查看的就是此编号。
属性 硬件IRQ编号 (hwirq) Linux IRQ编号 (irq)
定义者 中断控制器硬件厂商 Linux内核中断子系统
范围 依赖具体芯片(如0~223) 全局线性(通常0~NR_IRQS)
可见性 仅内核驱动可见 用户空间可见(procfs)
映射关系 通过irq_domain映射到Linux IRQ 直接用于注册中断处理函数
实践提示:在配置CPU亲和性时,我们操作的是Linux IRQ编号。例如,网卡队列的IRQ编号可以通过 cat /proc/interrupts | grep eth0 查看,第一列即为irq编号。
IRQ编号映射关系图 IRQ编号映射关系 硬件设备 中断控制器 内核中断子系统 映射流程说明: 1. 硬件设备触发中断,中断控制器产生 hwirq(如 GIC 中断号 32) 2. 中断控制器通过 irq_domain 查找映射表,将 hwirq 转换为 Linux IRQ 编号 3. 内核使用 Linux IRQ 编号注册处理函数、配置亲和性(如 /proc/irq/77/smp_affinity)

4.2 中断描述符:中断的完整档案

每个Linux IRQ编号都对应一个struct irq_desc结构体,称为中断描述符。它是内核管理中断的核心数据结构,包含了中断的所有状态和配置信息。

// include/linux/irqdesc.h (简化结构)
struct irq_desc {
    struct irq_common_data  irq_common_data;
    struct irq_data         irq_data;
    unsigned int __percpu   *kstat_irqs;    // 中断统计计数
    irq_flow_handler_t      handle_irq;     // 中断流处理函数
    struct irqaction        *action;        // 中断动作链表(处理函数)
    unsigned int            status_use_accessors; // 中断状态
    struct cpumask          *irq_affinity;  // CPU亲和性掩码
    const char              *name;          // 中断名称(如 "eth0-TxRx-0")
} ____cacheline_internodealigned_in_smp;
字段 作用 亲和性配置相关
irq_affinity CPU亲和性掩码,决定中断发往哪些CPU 直接修改此掩码即可改变中断路由
action 链表,挂载该中断的所有处理函数 网卡驱动通过 request_irq() 注册
kstat_irqs 每个CPU的中断计数 通过 /proc/interrupts 查看分布
handle_irq 流处理函数,决定中断处理流程 通常为 handle_fasteoi_irq
性能关键点:中断描述符中的 irq_affinity 字段是软中断CPU亲和性配置的底层操作对象。当用户写入 /proc/irq/77/smp_affinity 时,内核实际修改的就是此字段。配置不当会导致所有中断集中在CPU0,造成单核瓶颈。
中断描述符结构图 中断描述符 (struct irq_desc) 结构 struct irq_desc (中断描述符) irq_affinity (亲和性掩码) action (处理函数链表) kstat_irqs (统计计数) handle_irq (流处理) 亲和性配置路径: 用户空间写入 /proc/irq/{N}/smp_affinity → 内核修改 irq_desc->irq_affinity → 中断控制器重路由 每个中断描述符独占一个缓存行(____cacheline_internodealigned_in_smp),避免伪共享

4.3 中断控制器:中断路由的硬件枢纽

中断控制器(Interrupt Controller)是硬件层面的中断管理单元,负责收集设备中断信号、进行优先级仲裁,并将中断分发给指定的CPU。在ARM64和x86平台上,常见的中断控制器包括:

  • GIC (Generic Interrupt Controller):ARM平台标准中断控制器,支持SPI(共享外设中断)和PPI(私有外设中断)。
  • APIC (Advanced Programmable Interrupt Controller):x86平台中断控制器,包括LAPIC(本地APIC)和IOAPIC(I/O APIC)。
  • MSI/MSI-X (Message Signaled Interrupts):通过PCIe总线直接发送中断消息,无需专用中断线。
特性 GIC (ARM64) APIC (x86) MSI-X (PCIe)
中断分发方式 通过GICD(分发器)路由到指定CPU IOAPIC接收,LAPIC接收 直接写入目标CPU的LAPIC/MSI寄存器
亲和性配置 GICD_ITARGETSR寄存器 IOAPIC RTE(重定向表项) MSI-X Table中的Target CPU字段
中断数量 通常支持 1024 个SPI IOAPIC支持 24 个中断 每个设备最多 2048 个中断向量
性能优势 支持中断分组和优先级 支持中断重定向和负载均衡 每个队列独立中断,适合多队列网卡
多队列网卡最佳实践:现代40G/100G网卡(如Mellanox ConnectX-5、Intel XL710)使用MSI-X中断,每个硬件队列分配独立的MSI-X向量和独立的IRQ编号。这使得我们可以为每个队列的IRQ设置不同的CPU亲和性,实现1队列绑定1CPU的极致性能隔离。
中断控制器架构图 中断控制器架构与中断路由路径 网卡设备 存储设备 GPU设备 中断控制器 (GIC/APIC) CPU0 CPU1 CPU2 CPU3 亲和性配置点: • 中断控制器路由表 • MSI-X Table条目 • irq_desc->irq_affinity • /proc/irq/{N}/smp_affinity

4.4 中断处理流程:从硬件到软中断

理解中断的完整处理流程,有助于定位亲和性配置的生效点。一个典型的中断处理分为上半部和下半部:

  1. 硬件阶段:设备触发中断信号 → 中断控制器仲裁 → 发送到目标CPU。
  2. 上半部(硬中断):CPU保存现场 → 调用 handle_irq() → 执行 action 链表中的处理函数(如网卡驱动 ixgbe_msix_clean)。
  3. 下半部(软中断):驱动在硬中断中标记软中断(如 NET_RX_SOFTIRQ)→ 退出硬中断后,CPU执行软中断处理函数(如 net_rx_action)。
亲和性生效点:中断控制器根据 irq_affinity 决定将中断发送到哪个CPU。因此,亲和性配置直接影响硬中断在哪个CPU上执行,进而影响软中断的CPU分布(软中断默认在硬中断所在的CPU上执行)。这就是为什么配置IRQ亲和性可以控制协议栈收包处理所在的CPU。
中断处理流程图 中断处理流程:从硬件到协议栈 硬件中断触发 中断控制器路由 硬中断处理 (上半部) 软中断处理 (下半部) 亲和性配置影响点: ① 中断控制器路由阶段:根据 irq_affinity 选择目标CPU → 亲和性配置在此生效 ② 硬中断处理阶段:在目标CPU上执行驱动注册的 handler(如网卡驱动的 msix_clean) ③ 软中断处理阶段:默认在同一个CPU上执行 net_rx_action() → 协议栈收包处理 结论:配置IRQ亲和性 = 控制协议栈收包处理所在的CPU

4.5 关键数据结构关系总结

将IRQ编号、中断描述符、中断控制器三者的关系总结如下:

组件 层次 核心作用 亲和性配置接口
IRQ编号 软件抽象层 唯一标识一个中断源,用户空间操作对象 /proc/irq/{N}/smp_affinity
中断描述符 内核管理层 存储中断状态、处理函数、亲和性掩码 irq_desc->irq_affinity
中断控制器 硬件抽象层 物理路由中断信号到指定CPU GICD_ITARGETSR / IOAPIC RTE / MSI-X Table
性能优化启示:理解这三层结构后,我们可以得出一个关键结论——IRQ亲和性配置的本质是修改中断描述符中的CPU掩码,并通过中断控制器硬件实现物理路由。在后续章节中,我们将基于此原理,深入探讨如何为多队列网卡配置最优的亲和性策略,实现协议栈收包处理的CPU隔离和负载均衡。