問題描述
Linux IRQ 處理程序中的固有競爭條件 (Inherent race condition in Linux IRQ handlers)
假設有一個端口映射的 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:
Scenario 2 is the correct one. Interrupts handlers are running with interrupts disabled on the local CPU. So after returning from your handler, the interrupt controller will see that another interrupt occured and your handler will get called again.
What may happen though is that you may miss some interrupts if your are not fast enough and multiple interrupts happen while your are still handling the first one. This should not happen in your case because you have to clear the pending interrupt.
Andy's answer is about another issue. You definitively have to lock access to your device and resources because your handler may run concurrently on different CPUs.
方法 2:
On SMP systems there is clearly a possibility to have a race. Interrupts are local to the CPU since most of them implementing LAPIC controllers. Thus, you have to protect your data and device access by critical section synchronization algorithm. Due to interrupt context most of suitable here is
spin_lock_irqsave()
.(by Vilhelm Gray、Alexandre Belloni、0andriy)
參考文件