2012-12-14 48 views
0

我有一個使用handle_level_irq()的IRQ。大多數情況下,ISR要求安排下半部分,但有時候,它可以確定它是虛假的,並且不希望安排下半部分(出於性能原因)。問題是,在後一種情況下,存在競爭條件。如果ISR確定它是虛假的,它將揭露中斷並準備退出(注意 - 此時ISR不受desc->lock的保護)。但之後,中斷在第二個CPU上被觸發,第二個CPU根據handle_level_irq()抓取desc->lock,屏蔽IRQ,確定第一個CPU上的ISR正在進行,因此它解鎖並退出desc->lock。第一個CPU上的原始ISR也會退出,並始終屏蔽中斷。Linux IRQ:在ISR內解除IRQ

我希望能夠不安排下半部分,除非我需要,那麼有什麼方法讓ISR在避免上述競爭條件的同時揭露自己?

回答

0

問題是IRQ是級別觸發器,你有一個虛假的值。假如它正在接收虛假的中斷,那麼級別值如何解析?即,由於虛假的性質,該中斷當前處於活動級別。這就是爲什麼Linux屏蔽中斷以防止虛假中斷造成CPU死鎖的原因。

您可以將中斷級別更改爲邊沿觸發,並在下一個邊沿切換回級別觸發。這將消除虛假級別,直到硬件取消置位爲止。當硬件重新觸發中斷時,邊沿會發生,此時觸發電平可以重新安裝。

因此,除非共享中斷線,否則大多數外設都是邊沿觸發的。這個問題可能在你的中斷控制器中,而不是在handle_level_irq()的代碼中。您尚未提供版本或提供了您使用的驅動程序。

如果該行不共享,並且您的控制器支持邊緣觸發,我會將您的代碼轉換爲使用邊緣。請參閱Wikipedia