淺談Linux中斷處理(一)

來源:互聯網
上載者:User

注: 先做個引子,留給自己看,這一系列後續會繼續完善。本篇下面內容為轉載內容。

 

    在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個,本質上都是一樣的。作為外設,應當能夠處理自己中斷未被處理的情況。

 

 

原文出處:

http://www.linuxforum.net/forum/printthread.php?Cat=&Board=linuxK&main=550260&type=thread

資源連結:http://blog.csdn.net/normalnotebook

    一般申請中斷的時候都允許開中斷,即不使用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個,本質上都是一樣的。作為外設,應當能夠處理自己中斷未被處理的情況。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.