0

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

除非我需要,否则我希望能够不安排下半部分,那么 ISR 是否有某种方法可以在避免上述竞争条件的同时揭露自身?

4

1 回答 1

0

问题是 IRQ 是电平触发,你有一个虚假的值。如果电平值接收到虚假中断,它应该如何自行解决?即,由于虚假的性质,中断当前处于活动级别。这就是 Linux 屏蔽中断以防止 CPU 因虚假中断而死锁的原因。

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

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

如果线路未共享并且您的控制器支持边缘触发,我会将您的代码转换为使用边缘。在维基百科上查看更多信息。

于 2013-11-29T16:10:10.433 回答