1. 中断基础概念
1.1 中断的定义
中断(Interrupt)是一种硬件或软件触发的机制,用于暂停当前正在执行的程序,转而执行一个优先级更高的处理程序(中断服务例程,ISR),待处理完成后恢复原程序的执行。在 PCI/PCIe 设备驱动中,中断是设备通知 CPU 数据就绪、传输完成或错误发生的主要异步通信手段。
核心要点:中断避免了 CPU 轮询设备状态带来的性能浪费,是高性能外设驱动的基础。
1.2 中断类型:硬件中断与软件中断
| 类型 | 触发源 | 典型用途 | 示例 |
|---|---|---|---|
| 硬件中断 | 外设、定时器、其他硬件信号 | 通知 CPU 外设事件(如数据到达、DMA 完成) | PCIe 设备 MSI/MSI-X 中断、网卡 RX 中断 |
| 软件中断 | CPU 执行指令(如 INT n、系统调用) | 系统调用、异常处理、任务切换 | x86 的 INT 0x80、ARM 的 SVC |
在 PCI MSI 上下文中,我们主要关注硬件中断。MSI(Message Signaled Interrupt)和 MSI-X 属于硬件中断的变体,它们通过向特定内存地址写入消息来触发中断,取代了传统的边带信号线(INTx)。
1.3 中断向量
中断向量(Interrupt Vector)是一个数字标识符,用于在中断向量表(IVT)或中断描述符表(IDT)中索引对应的中断服务例程(ISR)。每个中断源被分配一个唯一的向量号,CPU 在响应中断时根据该向量号跳转到正确的处理函数。
PCI MSI 关联:MSI 中断允许设备通过写入消息数据(Message Data)来指定向量号,从而在无需物理中断引脚的情况下实现灵活的中断路由。
1.4 中断优先级
中断优先级(Interrupt Priority)决定了当多个中断同时发生时,CPU 先响应哪一个。高优先级中断可以抢占低优先级中断的处理。在 x86 架构中,优先级由中断向量号隐含决定(向量号越小优先级越高),而在 ARM GIC 中则通过独立的优先级寄存器配置。
| 架构 | 优先级机制 | 典型范围 | PCI MSI 影响 |
|---|---|---|---|
| x86 (APIC) | 向量号决定优先级(0 最高) | 0-255 | MSI 向量号需避开系统保留区间 |
| ARM GICv2/v3 | 独立优先级寄存器(0-255) | 0-255 | MSI 中断可配置为不同优先级组 |
| RISC-V PLIC | 中断源优先级可编程 | 0-7 | MSI 映射到 PLIC 中断源 |
驱动开发注意:在切换 MSI 中断模式时,驱动必须确保分配的向量号不与系统关键中断(如时钟、IPI)冲突,否则可能导致系统不稳定或死锁。
1.5 中断嵌套
中断嵌套(Interrupt Nesting)是指一个中断服务例程(ISR)正在执行时,又被另一个更高优先级的中断所打断。嵌套深度受限于中断控制器的硬件支持和内核的软件策略。
在 Linux 内核中,中断嵌套行为受以下因素控制:
- 中断标志位(IF):CPU 的 EFLAGS 寄存器中的 IF 位决定是否允许中断嵌套。
- 中断上下文:Linux 将中断处理分为上半部(hardirq)和下半部(softirq/tasklet),上半部默认关闭本地中断,防止嵌套;下半部则允许中断。
- MSI 特殊性:MSI 中断通常作为边沿触发处理,不会像电平触发那样产生重复中断,因此嵌套风险较低,但仍需注意优先级反转问题。
驱动适配要点:在 PCI MSI 模式下,驱动应使用
request_irq() 或 request_threaded_irq() 注册 ISR,并合理设置 IRQF_DISABLED 标志来控制嵌套行为。对于高性能设备,推荐使用 threaded IRQ 配合 MSI-X 多队列,以平衡嵌套延迟和吞吐量。
1.6 中断基础概念总结
| 概念 | 定义 | PCI MSI 关联 |
|---|---|---|
| 中断 | 暂停当前程序,执行紧急处理 | MSI 是设备触发中断的现代方式 |
| 硬件中断 | 由外设信号触发 | MSI/MSI-X 属于硬件中断 |
| 中断向量 | 标识 ISR 的数字索引 | MSI Message Data 指定向量号 |
| 中断优先级 | 决定中断响应顺序 | 向量号/优先级寄存器配置 |
| 中断嵌套 | 高优先级中断打断低优先级 ISR | MSI 边沿触发减少嵌套风险 |