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

Vil*_*ray 3 linux interrupt race-condition linux-kernel interrupt-handling

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

此外,假设通过以下方式将跟随中断处理程序分配给相关的IRQ线request_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;
}
Run Code Online (Sandbox Code Playgroud)

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

我可以想到三种情况:

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

Ale*_*oni 5

场景2是正确的.中断处理程序在本地CPU上禁用中断的情况下运行.因此,从处理程序返回后,中断控制器将看到发生了另一个中断,并且将再次调用您的处理程序.

可能会发生的情况是,如果您的速度不够快,并且在您仍在处理第一个中断时发生多次中断,则可能会错过一些中断.在您的情况下不应该发生这种情况,因为您必须清除挂起的中断.

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