PCIE 中断设计

三种中断触发模型:

1. Legacy  PCI Interrupt Delivery

这是PCI 总线的中断方式,跟寻常理解的中断触发方式一样,通过引脚的电平信号触发。一共有四根中断线(INTA, INTB, INTC, INTD).在常规的系统中一般会将这四根中断线或在一起然后传递给中断控制器。

PCIe为了向下兼容,也为了减少引脚数量,也支持Legacy 中断方式,但是不再有INTA-D这样具体的硬件信号线。

主要场景如下图:

PCI/PCI-X 设备接入 PCIe Bridge,PCIe Bridge收到legacy interrupt的中断电平信号将其转成 INTx Message TLP上发给RC,由RC将这个中断传递给中断控制器。

Legacy Interrupt 示例

PCI Device的INT信号接到南桥中断控制芯片PIC,PIC的中断信号INTR接入CPU

  1. 当Device发生中断事件,INTA硬件信号拉起,此时中断控制器PIC收到中断信号并把它发送给CPU(PIC控制的中断有很多,这些中断信号一起或给cpu)。
  2. CPU收到了中断,需要确认是哪个中断需要处理,于是通过处理器总线发出“Interrupt Acknowledge”的特殊指令
  3. PIC收到这个指令,会返回8-bit的Interrupt Vector来表示目前pending的最高优先级的中断向量
  4. CPU通过这个Vector从Interrupt Table中找到对应的handler。
  5. 在handler中完成业务,并向device下发指令拉低INTA信号

SMP系统支持

上面的示例是单CPU的情况下,SMP系统场景下,每个CPU都会有各自的业务,这些业务都会依赖device中断,所以先前的单cpu模型那种一根中断线的设计无法满足需求。硬件的中断信号线只有一根,如果接给一个cpu那没有问题,如果接给多个cpu,当中断发生,每个cpu都会收到中断信号,那么无论这个中断与这个CPU是否相关,每个cpu都要发出Interrupt Acknowledge给PIC查询,这样的设计冗余且低效而且混乱。

针对SMP系统推出APIC Model,有 IO-APIC(Advanced Programmable Interrupt Controller)这么个中断控制器。其中包含一个APIC bus和Logic APIC组件。

这样PIC与CPU连接的不再是硬件的中断信号,而是一个APIC bus连接在每个cpu的Logic APIC模块上,这个APIC bus上传递中断message,中断的message里包含了Interrupt Vector。

CPU在开始初始化各自的Logic APIC,静态分配中断,当中断产生,每个cpu的Logic APIC都会收到message,然后根据先前的配置,决定是否将中断报给CPU。因为先前已经配置好了,虽然每个Local APIC依然会收到这些message,但是CPU能够判断这这个中断的message是不是给自己的(甚至在Local APIC就能屏蔽掉不是给自己的中断)。

这个设计确实有了很多提升,上图中IO APIC向CPU传递中断的信号从单信号线变成了一个传递message的bus,但是对于外设(device)来说,其实它上报中断的手段并没有改变,还是中断信号线。在图上不难看出Device上报中断流

### PCIE 中断驱动开发解决方案 #### 了解PCIE中断机制 PCI Express (PCIE) 支持多种类型的中断,包括传统INTx中断、消息信号中断(MSI)以及扩展的消息信号中断(MSI-X)[^1]。这些中断机制允许设备向主机报告事件或状态变化。 对于Linux内核中的PCIE中断处理,通常会涉及到`pci_enable_msi()` 或 `pci_enable_msix()` 函数来启用MSI/MSI-X模式下的中断支持。当配置好之后,可以通过注册相应的IRQ处理器函数来进行具体的业务逻辑处理。 #### 编写PCIE中断驱动程序的关键要素 编写一个有效的PCIE中断驱动需要考虑以下几个方面: - **初始化阶段**:在驱动加载期间完成硬件资源分配并设置合适的参数;确保正确识别所使用的中断类型(如MSI或MSIX),并通过调用上述提到的相关API使能它们。 - **中断服务例程(ISR)**:定义ISR用于响应来自PCIE设备发出的中断请求。此过程可能涉及读取寄存器以获取更多信息,并执行必要的操作来清除待处理的状态位或其他标志。 - **错误恢复流程**:考虑到可能出现的各种异常情况,在设计时应加入适当的错误检测与修复措施。例如利用AER功能监控链路层发生的任何潜在问题,并采取行动防止进一步损害系统的稳定性。 ```c static irqreturn_t pcie_irq_handler(int irq, void *dev_id) { struct pci_dev *pdev = dev_id; // 处理特定于该设备的中断逻辑... return IRQ_HANDLED; /* 告诉系统已经成功处理 */ } ``` 为了实现更高效的性能优化,可以探索使用轮询方式代替传统的基于中断的方式,特别是在高频率数据交换场景下。这有助于减少CPU上下文切换开销,提高整体吞吐量[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值