linux中斷巢狀以及中斷丟失

2021-06-17 00:10:39 字數 1963 閱讀 4588

在linux核心裡,如果驅動在申請註冊中斷的時候沒有特別的指定,do_irq在做中斷響應的時候,是開啟中斷的,如果在驅動的中斷處理函式正在執行的過程中,出現同一裝置的中斷或者不同裝置的中斷,這時候新的中斷會被立即處理,還是被pending,等當前中斷處理完成後,再做處理。

在2.4和2.6核心裡,關於這一塊是否有什麼不同。

一般申請中斷的時候都允許開中斷,即不使用sa_interrupt標誌。如果允許共享則加上 sa_shirq,如果可以為核心熵池提供熵值(譬如你寫的驅動是ide之類的驅動),則再加上 sa_sample_random標誌。這是普通的中斷請求過程。對於這種一般情況,只要發生中斷,就可以搶占核心,即使核心正在執行其他中斷函式。這裡有兩點說明:一是因為linux不支援 中斷優先順序,因此任何中斷都可以搶占其他中斷,但是同種型別的中斷(即定義使用同乙個 中斷線的中斷)不會發生搶占,他們會在執行本型別中斷的時候依次被呼叫執行。二是所謂 「只要發生中斷,就可以搶占核心」這句是有一定限制的,因為當中斷發生的時候系統由中斷門 進入時自動關中斷(對於x86平台就是將eflags暫存器的if位置為0),只有當中斷函式被執行 (handle_irq_event)的過程中開中斷之後才能有搶占。 對於同種型別的中斷,由於其使用同樣的idt表項,通過其狀態標誌(irq_pending和 irq_inprogress)可以防止同種型別的中斷函式執行(注意:是防止handle_irq_event被重入, 而不是防止do_irq函式被重入),對於不同的中斷,則可以自由的巢狀。因此,所謂中斷巢狀, 對於不同的中斷是可以自由巢狀的,而對於同種型別的中斷,是不可以巢狀執行的。

以下簡單解釋一下如何利用狀態標誌來防止同種型別中斷的重入:

當某種型別的中斷第一次發生時,首先其idt表項的狀態位上被賦予irq_pending標誌,表示有待處理。 然後將中斷處理函式action置為null,然後由於其狀態沒有irq_inprogress標誌(第一次),故將其狀態置上irq_inprogress並去處irq_pending標誌,同時將action賦予相應的中斷處理函式指標(這裡是乙個重點,linux很巧妙的用法,隨後說明)。這樣,後面就可以順利執行handle_irq_event進行中斷處理,當在handle_irq_event中開中斷後,如果有同種型別的中斷發生,則再次進入do_irq函式,然後其狀態位上加上irq_pending標誌,但是由於前一次中斷處理中加上的irq_inprogress沒有被清除,因此這裡無法清除irq_pending標誌,因此action還是為null,這樣就無法再次執行handle_irq_event函式。從而退出本次中斷處理,返回上一次的中斷處理函式中,即繼續執行handle_irq_event函式。當handle_irq_event返回時檢查irq_pending標誌,發現存在這個標誌,說明handle_irq_event執行過程中被中斷過,存在未處理的同類中斷,因此再次迴圈執行handle_irq_event函式。直到不存在irq_pending標誌為止。

2.4和2.6的差別,就我來看,主要是在2.6中一進入do_irq,多了乙個關閉核心搶占的動作,同時在處理中多了一種對irq_per_cpu型別的中斷的處理,其他沒有什麼太大的改變。這類irq_per_cpu的中斷主要用在smp環境下將中斷繫結在某乙個指定的cpu上。例如arch/ppc/syslib/open_pic.c中的openpic_init中初始化ipi中斷的時候。

關於do_irq可能會丟失中斷請求。

do_irq函式是通過在執行完handle_irq_event函式之後判斷status是否被設定了irq_pending標誌來判斷是否還有沒有被處理的同一通道的中斷請求。 但是這種方法只能判斷是否有,而不能知道有多少個未處理的統一通道中斷請求。也就是說,假如在第乙個中斷請求執行handle_irq_event函式的過程中來了同一通道的兩個或更多中斷請求,而這些中斷不會再來,那麼僅僅通過判斷status是否設定了irq_pending標誌不知道到底有多少個未處理的中斷,handle_irq_event只會被再執行一次。

這算不算是個bug呢? 不算,只要知道有中斷沒有處理就ok了,知道1個和知道n個,本質上都是一樣的。作為外設,應當能夠處理自己中斷未被處理的情況。

linux中斷巢狀以及中斷丟失

在linux核心裡,如果驅動在申請註冊中斷的時候沒有特別的指定,do irq在做中斷響應的時候,是開啟中斷的,如果在驅動的中斷處理函式正在執行的過程中,出現同一裝置的中斷或者不同裝置的中斷,這時候新的中斷會被立即處理,還是被pending,等當前中斷處理完成後,再做處理。在2.4和2.6核心裡,關於...

中斷為何會丟失

正在讀ulk3,第四章中斷中關於 do irq 的 中涉及中斷丟失的部分有點迷惑。如下 spin lock irq desc irq lock irq desc irq handler ack irq irq desc irq status irq replay irq waiting irq de...

Linux中斷和中斷處理

眾所周知,處理器的速度跟外圍的硬體裝置的速度往往不在乙個數量級上,因此,如果核心採取讓處理器傳送乙個請求,然後專門等待回應的辦法,顯然差強人意。既然硬體處理的這麼慢,那麼核心就應該在這期間去處理其他事務,等待硬體真正完成了請求的操作後,再回過頭來對它進行處理。輪詢 polling 可能會是一種解決辦...