軟中斷一般而言在對時間要求較高的地方使用,常見的如網路
其分為八種型別
步驟函式
引數意義
1open_softirq
int nr, void(* action)(struct softirq_action *)
註冊nr型別的軟中斷,處理函式為action
2action
struct softirq_action *
中斷處理函式
3raise_softirq
int nr
觸發nr型別的軟中斷,設為掛起狀態,下次週期執行
其中在軟中斷執行時,允許響應中斷,也可被其他cpu再次啟用軟中斷,兩個同時執行,所以處理函式必須是可重入函式,唯一不響應中斷的時候就是在觸發中斷時raise_softirq
,在設掛起後響應中斷
tasklet建立在軟中斷上,但是對比直接使用軟中斷來說,tasklet有以下幾點區別
簡單的說軟中斷可併發在cpu上執行,所以需要多考慮併發的同步和互斥
tasklet杜絕了同乙個任務併發執行,但是可以不同的tasklet在不同的cpu上可以同時執行
struct tasklet_struct
;
其中taskelet狀態
tasklet_state_sched //tasklet已被掛起,尚未執行tasklet_state_run //tasklet正在執行
count
為tasklet引用計數器
0 //使能tasklet,此狀態下被設定掛起時,才可執行步驟1 //失能tasklet
函式引數意義1
declare_tasklet
name,func,data
建立乙個引用計數器為0的tasklet
1declare_tasklet_disabled
name,func,data
建立乙個引用計數器為1的tasklet
2tasklet_init
struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data
賦值乙個名為t的tasklet,其排程函式為func,data為排程函式的傳參,count為0
3func
unsigned long
實現排程函式
4tasklet_schedule
struct tasklet_struct *t
將名為t的tasklet標記掛起
5tasklet_disable
struct tasklet_struct *t
失能名為t的tasklet
6tasklet_enable
struct tasklet_struct *t
使能名為t的tasklet,與tasklet_disable成對使用
7tasklet_kill
struct tasklet_struct *t
將名為t的tasklet休眠,該函式可能會休眠
軟中段(包括tasklet)是人為申請觸發的,故而肯定會出現時而爆滿時而空閒的狀況,為了提高核心效率就必然會有一套動態效率控制的方法
ksoftirqd
為了解決軟中斷動態性數量而造成的核心效率問題,在每個處理器都有執行緒ksoftirqd
,它在軟中斷爆滿時喚醒,此執行緒優先順序為最低,達到不搶占其他任務,卻肯定會執行的效果
示例場景:
當從中斷返回時觸發軟中段執行中斷下半部,在執行軟中斷時又可以重複觸發自身,形成迴圈,無限占用核心,當ksoftirqd
出現時,觸發的軟中斷優先順序被調到最低,在執行其他的重要任務後才執行軟中斷,避免了核心被一直占用的問題
均以2.6.19以後的核心**為例[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-zhapkuij-1596530329712)(
先看看關鍵的資料結構:
struct work_struct ;
其中,data
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-fhr9usar-1596530329714)(
struct delayed_work ;
struct workqueue_struct ;
其中workqueue
可分兩種
預設的工作者執行緒一般而言工作佇列會建立乙個預設的核心執行緒也稱為工作者執行緒自創工作者執行緒
worker thread
你也可以自己新開闢乙個執行緒,一般用預設執行緒
預設工作者執行緒api:
步驟函式
引數意義
1declare_work
name,void(func)(void)
建立乙個名為name的woke_struct,處理函式為func,函式引數為data
2func
void *data
實現處理函式
3schedule_work
struct work_struct *work
將work標記為掛起
4schedule_delayed_work
struct delayed_work *work,unsigned long delay
延時delay後將work標記為掛起
5flush_scheduled_work
void
等待工作佇列項全部執行完畢,期間休眠狀態
6cancel_delayed_work
struct delayed_work *work
取消延時的work
自創執行緒api:
步驟函式
引數意義
1create_workqueue
const char *name
2init_work
struct work_struct *work,void(func)(void)
賦值乙個work,處理函式為func,函式引數為work_struct中的data
3init_delayed_work
struct delayed_work *work, void(func)(void)
4queue_work
struct workqueue_struct*wq,struct work_struct *work
將work在wq中標記為掛起
5queue_delayed_work
struct workqueue_struct*wq,struct delayed_work *work,unsigned long delay
延時delay後將work在wq標記為掛起
6flush_workqueue
struct workqueue_struct*wq
等待wq工作項全部執行完畢,期間休眠狀態
7destroy_workqueue
struct workqueue_struct*wq
釋放建立的工作佇列
軟中斷、tasklet、工作佇列三者如何選擇
軟中斷、tasklet基本相近,tasklet基於軟中斷實現,如果對併發有要求可以使用軟中斷,否則一般而言都使用介面簡單的tasklet
工作佇列不同與兩者,其使用核心執行緒完成,工作在程序上下文,最大的特點就是可以睡眠,但是開銷較大
所以總結而言
Linux中斷子系統
linux kernel的中斷子系統之 一 一 前言 乙個合格的linux驅動工程師需要對kernel中的中斷子系統有深刻的理解,只有這樣,在寫具體driver的時候才能 1 正確的使用linux kernel提供的的api,例如最著名的request threaded irq request ir...
linux中斷子系統
參考引用 wowotech 乙個很好的linux技術部落格。一 概述 目的kernel管理硬體裝置的方式 輪詢 中斷。中斷效率高且反應快於輪詢,因為它利用了硬體本身執行指令前會做的 中斷電訊號週期輪詢 分類中斷分為同步 synchronous 和非同步 asynchronous 同步也稱為異常,由c...
中斷子系統
linux kernel的中斷子系統之 一 綜述 linux kernel的中斷子系統之 二 irq domain介紹 linux kernel的中斷子系統之 三 irq number和中斷描述符 linux kernel的中斷子系統之 四 high level irq event handler ...