INTx、MSI 与 MSI-X 中断路径
1. 三种中断模型
| 模型 | 硬件行为 | Linux 特点 |
|---|---|---|
| INTx | 设备断言 INTA#~INTD#,电平触发且可共享 | 需桥 swizzle 和平台 IRQ 映射 |
| MSI | 设备向特定地址写入消息数据 | 1、2、4…个向量,Capability 内保存消息 |
| MSI-X | 设备通过 BAR 内 Table/PBA 发送消息 | 向量更多,每项可独立屏蔽 |
MSI/MSI-X不是“额外的一根中断线”,而是设备发出的 Memory Write。Root Complex/ITS/MSI 控制器把消息转换成 CPU IRQ。
2. 目录分工
drivers/pci/msi/:
msi.c:MSI/MSI-X Capability、向量申请/释放、屏蔽和状态恢复;pcidev_msi.c:PCI 设备与通用 MSI Core 的连接;irqdomain.c:PCI MSI irqdomain 分配;legacy.c:没有层次 irqdomain 时的架构兼容路径;msi.h:内部描述符与辅助声明。
通用 MSI 框架还位于kernel/irq/msi.c;平台 ITS/中断控制器不在drivers/pci。
3. 驱动申请主链
现代驱动应使用:
1 | pci_alloc_irq_vectors_affinity(dev, min, max, flags, affd) |
入口pci_alloc_irq_vectors_affinity()位于msi/msi.c:1011,释放入口pci_free_irq_vectors()位于 1064 行。
申请成功不等于 handler 已安装。正确错误路径必须在已成功request_irq()的范围内逐个释放,再调用pci_free_irq_vectors()。
4. MSI 初始化
msi_capability_init()位于msi.c:430,主要工作包括:
- 限制请求向量数为设备支持的 2 的幂;
- 建立 MSI descriptors;
- 从 MSI domain 分配 Linux IRQ;
- 组织 Message Address/Data;
- 写 MSI Capability;
- 关闭 INTx 并使能 MSI。
多消息 MSI 的向量数和对齐受 Capability 限制。驱动不能假设请求max_vecs就一定得到相同数量。
5. MSI-X 初始化
msix_capability_init()位于msi.c:617:
- 从 MSI-X Capability 得到 Table/PBA 所在 BAR 和 offset;
- 映射 Table;
- 分配 descriptors 与 IRQ;
- 为每个 Table Entry 写 Message Address/Data;
- 清 Mask 并设置 MSI-X Enable。
MSI-X Table 位于设备 BAR,不能作为普通业务寄存器随意覆盖。设备复位或 D3 状态转换后,PCI Core/驱动需恢复相关状态。
6. IRQ Domain
在层次中断域系统中:
1 | PCI function MSI descriptor |
pci_msi_setup_msi_irqs()位于msi/irqdomain.c:11。实际消息地址和数据由父中断域irq_chip组合生成,PCI Core 不应硬编码 ARM64 ITS 寄存器。
7. INTx 路由
INTx 需要:
- 读取设备 Interrupt Pin;
- 跨桥执行 swizzle;
- 通过 DT
interrupt-map、ACPI_PRT或平台 hook 映射; - 设置
pdev->irq并使用共享 IRQ。
RK3588 DTS 中 PCIe 节点包含四项interrupt-map。Rockchip DWC 驱动建立 legacy interrupt domain,系统 IRQ handler 再分发 INTA~INTD。
8. RK3588 两种 MSI 形态
DWC Host 可以使用:
- DWC 自带 MSI controller:DWC 寄存器接收 MSI,统一系统 IRQ 进入
dw_handle_msi_irq(); - 外部 MSI parent/ARM GIC ITS:由 DT 和 irqdomain 决定。
分析具体板卡必须看最终 DTS 和启动日志,不能仅凭CONFIG_PCI_MSI=y判断走哪条硬件路径。
9. 电源与错误恢复
- suspend 前屏蔽业务中断并停止 DMA;
pci_save_state()保存标准与扩展能力状态;- resume/slot reset 后恢复 MSI/MSI-X,再允许设备产生中断;
- AER recovery 的
slot_reset()之后,驱动通常需要重建设备寄存器和队列; - surprise removal 后不可再访问 MSI-X Table BAR。
10. 排障
| 现象 | 检查 |
|---|---|
| 只能获得 1 个向量 | Capability 上限、MSI 2 的幂约束、domain 空间 |
-ENOSPC |
irqdomain/ITS ID、DWC 向量、CPU affinity 限制 |
| MSI 无中断但 INTx 正常 | MSI parent、消息地址路由、DWC MSI mask/status |
| 中断风暴 | handler 未清设备状态、INTx 电平未 deassert |
| resume 后无中断 | MSI/MSI-X 状态或设备内部队列未恢复 |
可用lspci -vv查看 MSI/MSI-X Enable,/proc/interrupts确认 IRQ 是否计数;两者分别证明“配置已打开”和“CPU 实际收到”,含义不同。
正在加载留言…