我有一个使用handle_level_irq()
的IRQ。大多数情况下,ISR要求对下半部分进行调度,但偶尔,它可以确定这是伪造的,并且不想调度下半部分(出于性能原因)。问题是,在后一种情况下,存在种族条件。如果ISR确定它是伪造的,它将取消屏蔽中断并准备退出(注意——此时ISR不受desc->lock
保护)。但随后,中断在第二个CPU上被触发,根据handle_level_irq()
,它获取desc->lock
,屏蔽IRQ,确定ISR在第一个CPU上进行,因此它解锁desc->lock
并退出。第一个CPU上的原始ISR也将退出,使中断始终处于屏蔽状态。
除非需要,否则我希望能够不安排下半场比赛,那么ISR有没有办法在避免上述比赛条件的同时揭开自己的面纱?
问题是IRQ是级别触发器,并且您有一个伪值。如果一个级别值接收到虚假中断,那么它应该如何自行解决?即,根据杂散的性质,中断当前处于活动级别。这就是Linux屏蔽中断以防止CPU死锁的原因。
您可以将中断级别更改为边缘触发,并在下一个边缘更改回级别触发。这将消除杂散电平,直到硬件取消断言。当硬件重新断言中断时,将发生边缘,此时可以重新安装触发电平。
由于这个原因,除非中断线是共享的,否则大多数外围设备都是边缘触发的。此问题可能出现在中断控制器中,而不是handle_level_irq()
代码中。您尚未给出版本或提供您使用的驱动程序。
如果线路不共享,并且您的控制器支持边缘触发,我会将您的代码转换为使用边缘。更多信息请访问维基百科。