Linux IRQ:在ISR中取消屏蔽IRQ

时间:2012-12-14 15:04:51

标签: linux-kernel isr softirq

我有一个使用handle_level_irq()的IRQ。大多数情况下,ISR要求安排下半部分,但有时候,它可以确定它是虚假的,并且不想安排下半部分(出于性能原因)。问题是,在后一种情况下,存在竞争条件。如果ISR确定它是假的,它将取消屏蔽中断并准备退出(注意 - 此时ISR不受desc->lock保护)。但是,在第二个CPU上触发中断,根据handle_level_irq(),抓取desc->lock,屏蔽IRQ,确定第一个CPU正在进行ISR,因此解锁{{1退出。然后第一个CPU上的原始ISR也会退出,中断一直被中断。

我希望能够不安排下半部分,除非我需要,所以ISR是否有某种方法可以在避免上述竞争条件的同时取消屏蔽?

1 个答案:

答案 0 :(得分:0)

问题是IRQ是级触发器,你有一个虚假的值。如果一个级别值正在接收虚假中断,它将如何自行解决?即,由于 spurious 的性质,中断当前处于活动级别。这就是为什么Linux屏蔽中断以防止带有虚假中断的CPU死锁的原因。

您可以将中断级别更改为边沿触发,并在下一个边沿更改回级别触发。这将取消虚假级别,直到硬件取消断言。当硬件重新断言中断时,将发生边沿,此时可以重新安装级别触发。

因此,除非共享中断线,否则大多数外设都会被边沿触发。此问题可能在您的中断控制器中,而不是handle_level_irq()代码中。您尚未提供版本或提供您使用的驱动程序。

如果该行未共享且您的控制器支持边缘触发,我会将您的代码转换为使用边缘。请参阅Wikipedia