假设有一个端口映射的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;
}
这个IRQ处理程序中是否存在固有的竞争条件?例如,如果设备在"清除IRQ" outb
调用之后但在handler
函数返回之前生成另一个中断IRQ_HANDLED
,会发生什么?
我可以想到三种情况:
由于设备和Linux内核之间的死锁,IRQ线冻结并且无法再处理.
handler
返回后,Linux内核立即再次执行,以便处理第二个中断.
Linux内核中断handler
第二次调用handler
.
小智.. 5
场景2是正确的.中断处理程序在本地CPU上禁用中断的情况下运行.因此,从处理程序返回后,中断控制器将看到发生了另一个中断,并且将再次调用您的处理程序.
可能会发生的情况是,如果您的速度不够快,并且在您仍在处理第一个中断时发生多次中断,则可能会错过一些中断.在您的情况下不应该发生这种情况,因为您必须清除挂起的中断.
安迪的回答是另一个问题.您最终必须锁定对设备和资源的访问权限,因为您的处理程序可能在不同的CPU上并发运行.
场景2是正确的.中断处理程序在本地CPU上禁用中断的情况下运行.因此,从处理程序返回后,中断控制器将看到发生了另一个中断,并且将再次调用您的处理程序.
可能会发生的情况是,如果您的速度不够快,并且在您仍在处理第一个中断时发生多次中断,则可能会错过一些中断.在您的情况下不应该发生这种情况,因为您必须清除挂起的中断.
安迪的回答是另一个问题.您最终必须锁定对设备和资源的访问权限,因为您的处理程序可能在不同的CPU上并发运行.