我们是否必须在每一层上启用或禁用 PCI 中断,或者仅在最接近硬件的层上启用或禁用 PCI 中断?

Do we have to enable or disable PCI interrupts on every layer, or only at the closest to hardware?

我正在实现一个 PCIe 驱动程序,我想了解中断可以或应该是什么级别 enabled/disabled。我有意不指定 OS,因为我假设它应该与任何平台相关。我所说的级别是指以下内容:

我知道无论 PCIe 上使用何种中断类型(INTx 仿真、MSI 或 MSI-X),它都必须传送到主机 OS。

所以我的问题真的是——我们真的必须在每一层上启用或禁用中断,还是只在最接近硬件的地方就足够了,例如在相关的 PCI 寄存器中?

在不同级别禁用中断通常有完全不同的目的。

禁用中断:

  • 在OS(真的,这意味着在CPU) - 这通常是关于避免竞争条件。特别是,如果 state/memory 损坏可能发生在特定代码段期间,如果 CPU 恰好被中断,则该代码段将需要禁用中断处理。中断处理程序不得获取普通锁(根据定义,它们不能被挂起),并且它们不得尝试获取当前在 相同 上调度的线程持有的自旋锁CPU(因为该线程被同一个中断处理程序阻止继续运行!)因此使用中断处理程序确保数据安全可能很棘手。及时处理中断通常是一件好事,因此您希望在您编写的任何代码中绝对减少此类部分。尽可能多地在 辅助中断 处理程序中进行中断处理,以避免出现这种情况。辅助中断处理程序实际上只是常规 OS 线程上的回调,它没有主中断处理程序的任何限制。
  • PCI/PCIe 配置 - 据我了解,这主要是关于 路由 中断,并且是您通常在您的驱动程序加载(或由客户端激活)并在您的驱动程序卸载(或停用)时再次加载。这也可能受到电源管理事件的影响。在某些 OSes 中,当您通过更高级别的 API 激活 PCI 设备中断时,实际上会为您处理 PCI(e) 级别。
  • On-device - 这通常是一种优化,以避免在 CPU 不需要中断时中断它。最常见的场景是设备上发生了事件,因此产生了中断。如果驱动程序需要进行任何处理,驱动程序的主要中断处理程序将检查设备寄存器。如果是这样,它 禁用 设备上的中断,并将驱动程序的 辅助 中断处理程序安排到 运行。 OS 最终成为辅助处理程序,它处理设备提供的任何信息,直到它 运行 无事可做。然后它再次 启用 中断,再次检查设备是否有任何待处理的工作,如果有 none,它会终止。 (如果在最后一次检查中有要处理的项目,它会重新禁用中断并从头开始。)这个想法是,在辅助中断处理程序完成处理之前,真的没有必要触发主中断处理程序,并且浪费资源,如果有额外的事件到达,因为驱动程序已经忙于处理事件队列。重新启用中断后的最后检查是为了避免事件到达和重新启用中断之间的竞争条件。

我希望这能回答你的问题。