歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核學習筆記:中斷的下半部分

因為中斷的處理過程中,同種類型的中斷是被禁止的。並且中斷處理應該越短越好,這樣才能減少丟失的中斷。所以linux將中斷處理分為兩部分。關鍵緊急的事情在中斷上下文處理,不緊急或者花費時間較多的事情在所謂的下半部分中執行。中斷的下半部分是一種內核機制,它運行的時候允許中斷的產生,可以分為軟中斷與工作隊列。軟中斷又包含:tasklet 與內核定時器。軟中斷是一種特殊的內核控制路徑,它不屬於任何進程,所以不能被搶占,不可以睡眠。而工作隊列是一種內核線程,有工作的時候醒來工作,沒事的時候處於睡眠狀態。

相關閱讀:Linux內核學習筆記:中斷與異常 http://www.linuxidc.com/Linux/2012-03/57751.htm

一. 軟中斷

軟中斷是靜態分配的,這也就意味這如果想定義新的軟中斷就必須重新編譯內核。軟中斷可以並發的運行在多處理器上,即使同一個軟中斷也是這樣。所以,軟中斷函數必須是可重入函數,而且需要使用自選鎖來保護數據結構。linux使用有限數量的軟中斷,一般而言不需要定義新的軟中斷,因為tasklet就足夠用了。而且tasklet不必是可重入的。目前linux使用以下幾種軟中斷:搞優先級的tasklet,內核定時器,網卡接收軟中斷,網卡發送軟中斷,SCSI命令處理軟中斷,低優先級的軟中斷。

軟中斷使用的數據結構是softirq_vec數組,該數組包含softirq_action的32個元素,也就意味著linux總共可以有32個軟中斷。softirq_action結構有兩個域:一個是action指針一個是data。與軟中斷相關的進程描述符的字段是thread_info裡面的preempt_count。它包含:搶占計數器,軟中斷計數器,中斷計數器。內核用來了解進程運行的環境。in_interupt函數讀取這個字段,只要有一個計數器不為0,那麼就返回1.說明進程運行在中斷上下文,這時是禁止內核搶占的。

內核處理軟中斷需要三步:(1)初始化軟中斷,初始化softirq_vec數組,初始化軟中斷處理函數以及所使用的數據結構。(2)激活軟中斷。raise_softirq激活軟中斷。(3)周期性檢查,並處理軟中斷。內核在do_IRQ完成中斷處理調用irq_exit的時候會檢查未處理的軟中斷。或者在ksoftirqd/n線程被喚醒時檢查軟中斷。

如果確實有未處理的軟中,那麼內核調用do_softirq函數處理軟中斷。這個函數依次處理激活的軟中斷,執行注冊的函數。主要完成以下幾步:

(1)調用in_interrupt,如果返回1說明處於中斷上下文。函數返回。

(2)調用__do_softirq函數

這個函數是處理軟中斷的基本函數,它主要吧軟中斷的位掩碼復制到局部變量pending中,清除本地CPU的軟中斷位圖。根據pending的每一位執行對應的軟中斷處理函數。注意在軟中斷處理過程中可能產生新的軟中斷。所以,這個函數會循環執行,直到沒有新的軟中斷。

在軟中斷處理過程中,__do_softirq是循環執行的,如果有軟中斷不停的產生新的軟中斷,那麼會帶來一個問題就是__do_softirq會一直占用CPU,用戶進程沒有機會運行。但是如果__do_softirq不循環檢查新的軟中斷,那麼軟中斷就會延遲很久執行。為了解決這個問題,linux采用ksoftirqd內核線程的辦法。__do_softirq會循環有限次來處理新的軟中斷,如果還有新的軟中斷就會喚醒ksoftirqd內核線程來執行,這個內核線程的優先級比較低,所以即使有大量的軟中斷需要處理,對用戶進程的影響也比較小。

二. tasklet

tasklet也是一種軟中斷,但是tasklet比軟中斷有著更好的並發特性。是io驅動程序首選的可延遲函數方法。tasklet有如下的特性:

(1)tasklet可以在內核運行的時候定義

(2)相同類型的tasklet不能在用一個CPU上並發運行,也不能在不同的CPU上並發運行

(1)不同類型的tasklet不能在同一個CPU上並發運行,但是可以在不同的CPU上並發運行。所以如果不同的tasklet訪問相同的數據結構,需要加一定的鎖保護

三. 工作隊列

工作隊列由內核線程來執行。主要的數據結構是workqueue_struct結構。這個結構是是一個cpu_workqueue_struct的數組。cpu_workqueue_struct結構是工作哦隊列的基本結構。主要有此工作隊列工作的鏈表,還有內核線程的進程描述符的指針。工作隊列的工作是由work_struct結構組成,這個結構有需要執行的函數,以及傳輸的數據等字段。建立工作隊列是一項非常耗時的操作,因為它會建立一個內核線程。所以linux默認建立了一個工作隊列來供使用。每一個CPU一個這樣的工作隊列。

Copyright © Linux教程網 All Rights Reserved