轉+原創
中斷服務程序每每都是在CPU關中斷的條件下執行的,以免中斷嵌套而使控制複雜
化。可是CPU關中斷的時間不能太長,不然容易丟失中斷信號。爲此,Linux將中斷服務
程序一分爲二,各稱做「Top Half」和「Bottom Half」。前者一般對時間要求較爲嚴
格,必須在中斷請求發生後當即或至少在必定的時間限制內完成。所以爲了保證這種處
理能原子地完成,Top Half一般是在CPU關中斷的條件下執行的。具體地說,Top Half的
範圍包括:從在IDT中登記的中斷入口函數一直到驅動程序註冊在中斷服務隊列中的
ISR。而Bottom Half則是Top Half根據須要來調度執行的,這些操做容許延遲到稍後執
行,它的時間要求並不嚴格,所以它一般是在CPU開中斷的條件下執行的。
可是,Linux的這種Bottom Half(如下簡稱BH)機制有兩個缺點,也即:(1)在任
意一時刻,系統只能有一個CPU能夠執行Bottom Half代碼,以防止兩個或多個CPU同時來
執行Bottom Half函數而相互干擾。所以BH代碼的執行是嚴格「串行化」的。(2)BH函
數不容許嵌套。
這兩個缺點在單CPU系統中是可有可無的,但在SMP系統中倒是很是致命的。由於BH機
制的嚴格串行化執行顯然沒有充分利用SMP系統的多CPU特色。爲此,Linux2.4內核在BH
機制的基礎上進行了擴展,這就是所謂的「軟中斷請求」(softirq)機制。
Linux的softirq機制是與SMP緊密不可分的。爲此,整個softirq機制的設計與實現中
自始自終都貫徹了一個思想:「誰觸發,誰執行」(Who marks,Who runs),也即觸發
軟中斷的那個CPU負責執行它所觸發的軟中斷,並且每一個CPU都由它本身的軟中斷觸發與
控制機制。這個設計思想也使得softirq機制充分利用了SMP系統的性能和特色。 http://www.douban.com/note/245433620/
軟中斷是利用硬件中斷的概念,用軟件方式進行模擬,實現宏觀上的異步執行效果。不少狀況下,軟中斷和"信號"有些相似,同時,軟中斷又是和硬中斷相對應的,"硬中斷是外部設備對CPU的中斷","軟中斷一般是硬中斷服務程序對內核的中斷","信號則是由內核(或其餘進程)對某個進程的中斷"(《Linux內核源代碼情景分析》第三章)。
軟中斷的一種典型應用就是所謂的"下半部"(bottom half),它的得名來自於將硬件中斷處理分離成"上半部"和"下半部"兩個階段的機制:上半部在屏蔽中斷的上下文中運行,用於完成關鍵性的處理動做;而下半部則相對來講並非很是緊急的,一般仍是比較耗時的,所以由系統自行安排運行時機,不在中斷服務上下文中執行。bottom half的應用也是激勵內核發展出目前的軟中斷機制的緣由。
軟中斷是linux系統原「底半處理」的升級,在原有的基礎上發展的新的處理方式,以適應多cpu 、多線程的軟中斷處理。
軟中斷是實現系統API函數調用的手段
通常,系統程序由軟件公司實現且不開源,你沒法知道系統API函數的偏移地址,並且你寫的應用程序和軟件公司提供的系統程序是徹底分開的,編譯器沒法將兩者連接在一塊兒,同時,系統程序須要核心態特權才能運行,此時用函數調用的辦法是沒法調用系統API函數的。解決這個問題的方法是使用軟中斷,當應用程序須要調用API時,就先設置功能號(如AX=0H),而後觸發軟中斷(如INT 80H)。系統程序設置好中斷向量表。這樣,應用程序就能夠間接找到系統API了。
有了軟中斷,就能夠實現應用程序的動態加載。就像WINDOWS/Linux那樣,應用程序和系統程序分別開發,不在一塊兒編譯鏈接,應用程序經過軟中斷調用系統提供的功能。
Linux軟中斷原理淺析
Linux中的軟中斷機制用於
系統中對時間要求最嚴格以及最重要的中斷的下半部進行使用。(
中斷分上下部,上部一般對時間要求嚴格)在系統設計過 程中,你們都清楚中斷上下文不能處理太多的事情,須要快速的返回,不然很容易致使中斷事件的丟失,因此這就產生了一個問題:中斷髮生以後的事務處理由誰來 完成?在先後臺程序中,因爲只有中斷上下文和一個任務上下文,因此中斷上下文觸發事件,設置標記位,任務上下文循環掃描標記位,執行相應的動做,也就是中 斷髮生以後的事情由任務來完成了,只不過任務上下文采用掃描的方式,實時性不能獲得保 證。在
Linux系統和Windows系統中,這個不斷循環的任務就是本文所要講述的軟中斷daemon。在Windows中處理耗時的中斷事務稱之爲中 斷延遲處理,在Linux中稱之爲中斷下半部,顯然中斷上半部處理清中斷之類十分悠閒的動做,而後在退出中斷服務程序時觸發中斷下半部,完成具體的功能。
硬中斷是由外部事件引發的所以具備隨機性和突發性;軟中斷是執行中斷指令產生的,無面外部施加中斷請求信號,所以中斷的發生不是隨機的而是由程序安排好的。
在Linux中,中斷下半部的實現基於軟中斷機制。因此理清楚軟中斷機制的原理,那麼中斷下半部的實現也就很是簡單了。經過上述的描述,你們也應該 清楚爲何要定義軟中斷機制了,
一句話就是爲了要處理對時間要求苛刻的任務,剛好中斷下半部就有這樣的需求,因此其實現採用了軟中斷機制。
軟中斷是一種推後執行的機制,定時器,網卡的數據的處理是很典型的軟中斷,這個和中斷向 量表裏的中斷是徹底不同的,以網絡數據的處理爲例,當網卡接到一個數據包後,其中斷處理程序只是把數據複製到緩衝區,而後就告訴網卡,你能夠再傳數據給 我了,也就是中斷返回,但在此以前,網卡的中斷處理程序要置一個標誌位,告訴操做系統有事要作,這個事就是軟中斷,但軟中斷只是不少中斷返回時要作的事情 之一,操做系統每次中斷返回時會檢查着個標誌位,看是否有事要作,若是有,就會去處理,象前面提到的網卡,這時候操做系統就回調用軟中斷的處理函數,網卡 的軟中斷程序就是作分析數據包啊,這個數據應該傳給誰啊等這些工做.沒有,就返回了,除了必須的部分
構成軟中斷機制的核心元素包括:
一、 軟中斷狀態寄存器soft interrupt state(irq_stat)
二、 軟中斷向量表(softirq_vec)
三、 軟中斷守護daemon
軟中斷的工做工程模擬了實際的中斷處理過程,當某一軟中斷時間發生後,首先須要設置對應的中斷標記位,觸發中斷事務,而後喚醒守護線程去檢測中斷狀 態寄存器,若是經過查詢發現某一軟中斷事務發生以後,那麼經過軟中斷向量表調用軟中斷服務程序action()。這就是軟中斷的過程,與硬件中斷惟一不一樣 的地方是從中斷標記到中斷服務程序的映射過程。在CPU的硬件中斷髮生以後,CPU須要將硬件中斷請求經過向量表映射成具體的服務程序,這個過程是硬件自 動完成的,可是軟中斷不是,其須要守護線程去實現這一過程,這也就是軟件模擬的中斷,故稱之爲軟中斷。
一個軟中斷不會去搶佔另外一個軟中斷,只有硬件中斷才能夠搶佔軟中斷,因此軟中斷可以保證對時間的嚴格要求。
Linux中軟中斷實現分析
在Linux中最多能夠註冊32個軟中斷,目前系統用了6個軟中斷,他們爲:定時器處理、SCSI處理、網絡收發處理以及Tasklet機制,這裏的tasklet機制就是用來實現下半部的,
描述軟中斷的核心數據結構爲中斷向量表,其定義以下:
struct softirq_action
{
void (*action)(struct softirq_action *); /* 軟中斷服務程序 */
void *data; /* 服務程序輸入參數 */
};
軟中斷守護daemon是軟中斷機制的實現核心,其實現過程也比較簡單,經過查詢軟中斷狀態irq_stat來判斷事件是否發生,若是發生,那麼映 射到軟中斷向量表,調用執行註冊的action函數就能夠了。從這一點分析能夠看出,軟中斷的服務程序的執行上下文爲軟中斷daemon。在Linux中 軟中斷daemon線程函數爲do_softirq()。
觸發軟中斷事務經過raise_softirq()來實現,該函數就是在中斷關閉的狀況下設置軟中斷狀態位,而後判斷若是不在中斷上下文,那麼直接喚醒守護daemon。
經常使用的軟中斷函數列表以下:
一、 Open_softirq,註冊一個軟中斷,將軟中斷服務程序註冊到軟中斷向量表。二、 Raise_softirq,設置軟中斷狀態bitmap,觸發軟中斷事務。
Tasklet機制實現分析
Tasklet爲一個軟中斷,考慮到優先級問題,分別佔用了向量表中的0號和5號軟中斷。
當tasklet的軟中斷事件發生以後,執行tasklet-action的軟中斷服務程序,該服務程序會掃描一個tasklet的任務列表,執行該任務中的具體服務程序。在這裏舉一個例子加以說明:
當用戶讀寫USB設備以後,發生了硬件中斷,硬件中斷服務程序會構建一個tasklet_struct,在該結構中指明瞭完成該中斷任務的具體方法 函數(下半部執行函數),而後將tasklet_struct掛入tasklet的tasklet_struct鏈表中,這一步能夠經過 tasklet_schedule函數完成。最後硬件中斷服務程序退出而且CPU開始調度軟中斷daemon,軟中斷daemon會發現tasklet發 生了事件,其會執行tasklet-action,而後tasklet-action會掃描tasklet_struct鏈表,執行具體的USB中斷服務 程序下半部。這就是應用tasklet完成中斷下半部實現的整個過程。
Linux中的tasklet實現比較簡單,其又封裝了一個重要數據結構tasklet_struct,使用tasklet主要函數列表以下:
一、 tasklet_init,初始化一個tasklet_struct,固然能夠採用靜態初始化的方法,宏爲:DECLARE_TASKLET。
二、 tasklet_schedule,調度一個tasklet,將輸入的tasklet_struct添加到tasklet的鏈表中。
Linux中的軟中斷機制就是模擬了硬件中斷的過程,其設計思想徹底能夠在其餘嵌入式OS中得以應用。