INTx、MSI 与 MSI-X 中断路径

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
2
3
4
5
6
7
8
9
10
pci_alloc_irq_vectors_affinity(dev, min, max, flags, affd)
-> 按 flags 优先尝试 MSI-X
-> 失败后尝试 MSI
-> 必要时回退 INTx
-> 返回实际向量数

pci_irq_vector(dev, nr)
-> Linux IRQ number

request_irq()/request_threaded_irq()

入口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,主要工作包括:

  1. 限制请求向量数为设备支持的 2 的幂;
  2. 建立 MSI descriptors;
  3. 从 MSI domain 分配 Linux IRQ;
  4. 组织 Message Address/Data;
  5. 写 MSI Capability;
  6. 关闭 INTx 并使能 MSI。

多消息 MSI 的向量数和对齐受 Capability 限制。驱动不能假设请求max_vecs就一定得到相同数量。

5. MSI-X 初始化

msix_capability_init()位于msi.c:617

  1. 从 MSI-X Capability 得到 Table/PBA 所在 BAR 和 offset;
  2. 映射 Table;
  3. 分配 descriptors 与 IRQ;
  4. 为每个 Table Entry 写 Message Address/Data;
  5. 清 Mask 并设置 MSI-X Enable。

MSI-X Table 位于设备 BAR,不能作为普通业务寄存器随意覆盖。设备复位或 D3 状态转换后,PCI Core/驱动需恢复相关状态。

6. IRQ Domain

在层次中断域系统中:

1
2
3
4
5
PCI function MSI descriptor
-> PCI MSI domain
-> parent MSI domain
-> ARM GIC ITS 或 DWC 内建 MSI 控制器
-> CPU interrupt

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 可以使用:

  1. DWC 自带 MSI controller:DWC 寄存器接收 MSI,统一系统 IRQ 进入dw_handle_msi_irq()
  2. 外部 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 实际收到”,含义不同。

文章互动

阅读 --

留言

0 条留言

正在加载留言…