Linux IRQ处理程序中固有的竞争条件

假设有一个端口映射的I / O设备在IRQ线上任意产生中断。 该器件的待处理中断可以通过对特定寄存器的单个outb调用来清除。

此外,假设通过request_irq将下面的中断处理程序分配给相关的IRQ行:

 irqreturn_t handler(int irq, void *data) { /* clear pending IRQ on device */ outb(0, CLEAR_IRQ_REGISTER_ADDR); /* device may generate another IRQ at this point, * but this handler function has not yet returned */ /* signal kernel that IRQ has been handled */ return IRQ_HANDLED; } 

在这个IRQ处理程序中是否存在固有的竞争条件? 例如,如果设备在“清除IRQ” outb调用之后,但在handler函数返回IRQ_HANDLED之前产生另一个中断,会发生什么情况?

我可以想到三种情况:

  1. 由于设备和Linux内核之间的死锁,IRQ线冻结,不能再进行处理。
  2. Linux内核返回后立即再次执行handler ,以处理第二个中断。
  3. Linux内核中断第二次调用handler

情景2是正确的。 中断处理程序在本地CPU上禁用中断的情况下运行。 所以从你的处理程序返回后,中断控制器将看到另一个中断发生,你的处理程序将再次被调用。

但是,可能发生的情况是,如果你的速度不够快,当你还在处理第一个中断的时候,你可能会错过一些中断。 这不应该发生在你的情况,因为你必须清除待处理的中断。

安迪的回答是关于另一个问题。 您最终必须锁定对设备和资源的访问权限,因为您的处理程序可以在不同的CPU上同时运行。

在SMP系统上显然有可能进行比赛。 中断是CPU本地的,因为其中大多数实现LAPIC控制器。 因此,您必须通过关键部分同步算法来保护您的数据和设备访问。 由于中断上下文,大多数适合的是spin_lock_irqsave()