先弄清兩個概念,程序上下文和中斷上下文
處理器總處於以下狀態中的一種:
1、核心態,執行於程序上下文,核心代表程序執行於核心空間;
2、核心態,執行於中斷上下文,核心代表硬體執行於核心空間;
3、使用者態,執行於使用者空間。
使用者空間的應用程式,通過系統呼叫,進入核心空間。這個時候使用者空間的程序要傳遞很多變數、引數的值給核心,核心態執行的時候也要儲存使用者程序的一些暫存器值、變數等。所謂的「程序上下文」,可以看作是使用者程序傳遞給核心的這些引數以及核心要儲存的那一整套的變數和暫存器值和當時的環境等。
硬體通過觸發訊號,導致核心呼叫中斷處理程式,進入核心空間。這個過程中,硬體的一些變數和引數也要傳遞給核心,核心通過這些引數進行中斷處理。所謂的「中斷上下文」,其實也可以看作就是硬體傳遞過來的這些引數和核心需要儲存的一些其他環境(主要是當前被打斷執行的程序環境)。
響應特定中斷時會執行對應的中斷處理程式,硬體通過中斷線通知核心發生了中斷,一條中斷線可以被共享.(大多數裝置都是共享中斷線,這意味著如果從一條中斷線接收到中斷,可能是這條中斷線上任何裝置發來的.)
核心會在do_irq()中呼叫handle_irq_enevt()來執行對應中斷線所安裝的所有中斷處理程式.
當中斷處理程式在執行時,相應的中斷線會被遮蔽.所以中斷處理程式不會被巢狀,即不用考慮可重入.簡化了編寫.
怎麼區分一條中斷線上的不同裝置?..
每乙個中斷處理程式裡還得檢測到底是不是對應的中斷產生.
在中斷處理程式中不能睡眠..
關於下半部:
下半部的存在是因為中斷處理程式中,是關本條中斷線中斷,或者關所有中斷的.為了要讓中斷處理程式盡快返回,所以把一些相對次要的工作交給下半部做.當然得註冊好下半部對映的處理程式,並觸發才行.
下半部到底什麼時候會執行呢?,即什麼時候執行do_softirq();
這個問題等下再談論,這裡只要知道會在中斷處理程式返回後的一段時間內執行.當然也是越快越好了.
先看下半部的實現機制.主要有五種
1.bh 2.5中除去
2.任務佇列 2.5中除去
3.軟中斷 2.3開始引入
4.tasklet 2.3開始引入
5.工作佇列 2.5開始引入
前兩種是過時的,新核心基本除去.
這裡主要討論下,軟中斷和tasklet.
軟中斷:
其資料結構表示為:
struct softirq
static struct softirq softirq_vec[32];
每個註冊的軟體中斷占該陣列的一項.因此最多只能有32個軟中斷.
軟中斷怎麼執行的呢?
首先軟中斷要被設定,有乙個對映這個數級的32位的點陣圖,通過softirq_pending()巨集的返回值,可以知道哪一位被設定.也就表示該軟中斷等待處理
在do_softirq()中..也就會根據這個位圖呼叫軟中斷的處理函式action;
軟中斷的處理函式也是不能睡眠的.
tasklet:
乙個tasklet基資料結構表示為:
struct task_struct
tasklet基於軟中斷實現,與軟體中斷的區別是
1:個數不會受限.軟體中斷只能是32個.而且不能像tasklet樣動態的註冊或去除.
2.相同的tasklet不能同時執行.不同的tasklet能同時在不同的處理器上執行
相同的軟中斷可以同時在所有處理器上執行.不同的也可以
為什麼說tasklet基於軟中斷實現?
因為tasklet的執行,是按這樣的流程來的.
通過tasklet_schedule()或tasklet_hi_schedule(優先不同)喚起軟中斷中的tasklet_softirq或hi_softirq.這樣在do_softirq()執行時就會執行這兩個軟中斷對應的處理函式tasklet_action()和tasklet_hi_action();
這兩個處理函式會掃瞄tasklet的鍊錶,然後呼叫具體的tasklet的執行函式(task_struct結構中的func,也是不能睡眠的).當然得進行一些檢查,關於count,state等字段.
有兩個巨集in_interrupt(),和in_irq().前乙個判斷核心是否正在執行中斷處理程式或下半部處理程式,後乙個只判斷核心是否正在執行中斷處理程式.
最後,來看軟中斷的執行時間,即do_softirq()的執行時間.
有兩種選擇:
1.中斷返回時馬上呼叫執行.這樣能對軟中斷即時處理.但是這樣
一直頻繁執行軟中斷了(因為有的軟中斷本身可能還會重複觸發).使用者程序很可能會處於飢餓狀態.
2.如果不馬上執行.比如延後到下一次執行時機再執行(一般是下一次中斷返回).但是這樣當系統空閒時,也必須得等一段時間.這樣利用率又不高.同時也可能有大量軟中斷得不到執行.
現在核心採用第二種方法,但通過乙個ksoftirqd執行緒來解決這一問題.這個執行緒就是迴圈呼叫do_softirq(),每個處理器有乙個這樣的執行緒.當有大量軟中斷,時該執行緒被喚醒.(do_softirq()中通過判斷是否有重複觸發,來決定喚醒ksoftirqd執行緒).
ksoftirqd的優先順序最低,所以不會搶占使用者程序,但當系統空閒時就會呼叫,從而解決了空閒時也得等一段時間才能處理軟中斷的問題.
學習筆記之中斷下半部
中斷下半部 由於中斷處理力求時間短,所以引出了下半部。tasklet工作在中斷上下文,處理中不允許休眠,而workqueue工作在程序上下文,這是不同點。1,softirq 處理比較快,但是核心級別的機制,需要修改整個核心原始碼,不推薦也不常用 2,tasklet 內部實現實際呼叫了softirq ...
中斷的上下半部
因為輸入類裝置的輸入都是非同步事件,因此一般使用中斷來處理和響應。當中斷處理程式比較長,而又希望優良的響應特性時,linux核心處理中斷的方案是 人為地將處理程式分為兩部分。1 為什麼要分上半部 top half,又叫頂半部 和下半部 bottom half,又叫底半部 2 下半部處理策略1 tas...
中斷下半部的妙用
中斷下半部 中斷處理程式是核心中很重要的一部分,但是由於本身存在著一些限制,所以他只能完成整個中斷處理程式中的上半部分。具體侷限如下 中斷處理程式是以非同步方式執行,並且他有可能會打斷其他重要的 甚至有可能是其他的中斷程式 的執行,因此為了避免被打斷的 停止時間過長。中斷處理程式要執行的越快越好 如...