Linux核心學習筆記五 中斷推後處理機制

2022-03-24 08:32:19 字數 4554 閱讀 8284

硬體通過中斷與作業系統進行通訊,通過對硬體驅動程式處註冊中斷處理程式,快速響應硬體的中斷。

硬體中斷優先順序很高,打斷當前正在執行的程式。有兩種情況:

硬體中斷在中斷處理程式中處理

硬體中斷延後再進行處理

這個具體硬體相關,在中斷處理程式中處理,打斷了當前正在執行的程式;所有中斷都將被遮蔽;如果占用時間太長不合適,

造成系統互動性,反應能力都會受到影響。 需要在其中判斷平衡:

如果乙個任務對時間非常敏感,將其放在中斷處理程式中執行;

如果乙個人和和硬體相關,將其放在中斷處理程式中執行;

如果乙個任務要保證不被其他中斷打斷,將其放在中斷處理程式中執行;

其餘情況考慮延後機制中執行——下半部。

軟中斷是在編譯期間靜態分配的,在程式執行前將軟中斷假如到表中。

下面看一下這個過程:

加入軟中斷型別:

linux3.5.3**:

enum

;

//軟中斷表:

static structsoftirq_actionsoftirq_vec[nr_softirqs]

//軟中斷結構體

struct

softirq_action

;

註冊軟中斷處理函式:

void open_softirq(int nr, void (*action)(struct softirq_action *))

觸發軟中斷:

void raise_softirq(unsigned int

nr)

執行軟中斷:

void irq_exit(void

)void __do_softirq(void

)

//下乙個軟中斷

h++;

//下乙個軟中斷狀態標誌位

pending >>= 1

; }

while

(pending);

local_irq_disable();

pending =local_softirq_pending();

if (pending && --max_restart)

goto

restart;

if(pending)

wakeup_softirqd();

lockdep_softirq_exit();

__local_bh_enable(softirq_offset);

}

軟中斷的基本結構如下圖表示:

軟中斷中表中有一種型別是:tasklet_softirq

tasklet就是利用軟中斷實現中斷推後處理機制。通常使用較多的是tasklet而不是軟中斷。

tasklet資料結構:

struct

tasklet_struct

;

state:

enum

;

count:為0允許啟用執行

宣告tasklet:可以動態或者靜態方式

靜態:

#define declare_tasklet(name, func, data) \

struct tasklet_struct name =

#define declare_tasklet_disabled(name, func, data) \

struct tasklet_struct name =

動態:

void tasklet_init(struct tasklet_struct *t,

void (*func)(unsigned long), unsigned long

data)

同時需要編寫tasklet處理函式。

排程tasklet:

void tasklet_hi_schedule(struct tasklet_struct *t)

執行tasklet處理程式:繼續看上面排程tasklet程式執行:

inline void raise_softirq_irqoff(unsigned int

nr)//

使用ksoftirqd核心執行緒來處理

static

void wakeup_softirqd(void

)

ksoftirqd核心執行緒:軟中斷才被觸發頻率很高,在處理過程中還會重新觸發軟中斷;執行會導致使用者空間程序無法獲得處理時間處於飢餓狀態;

對重新觸發的軟中斷立即處理,會導致佔據處理時間過長;不進行立即處理不合適;

對此解決方法:

l  只要還有被觸發並等待處理和過程中重新觸發的軟中斷的軟中斷,本次執行就要負責處理;軟中斷立即處理,使用者空間得不到執行時間。

l  不處理過程中觸發的軟中斷,放到下乙個中斷執行時機時處理。軟中斷得不到立即處理,系統空閒時造成不合理;保證使用者空間得到執行時間。

兩種方式有存在問題,只能在這其中採取這種的方式:

核心使用執行緒處理軟中斷,執行緒優先順序較低,可以被搶占;能夠保證軟中斷被處理,也能保證使用者空間程式得到執行時間。

每個cpu上有存在這樣乙個執行緒:ksoftirqd/0或者ksoftirqd/1……

static __init int spawn_ksoftirqd(void

)early_initcall(spawn_ksoftirqd);

static

int __cpuinit cpu_callback(struct notifier_block *nfb,

unsigned

long

action,

void *hcpu)

工作佇列(work queue)通過核心執行緒將中斷下半部分程式推後執行到執行緒中執行,工作佇列可以建立執行緒來處理相應任務。

工作佇列建立的執行緒為工作者執行緒:worker thread;系統提供預設的執行緒來處理工作者佇列。

工作者執行緒資料結構:

struct

workqueue_struct cpu_wq;

/*i: cwq's

*/struct list_head list; /*

w: list of all workqueues

*/……

}

cpu工作佇列資料結構:

struct

cpu_workqueue_struct ;

工作資料結構:

struct

work_struct ;

宣告工作佇列:靜態:

#define declare_work(n, f)                             \

struct work_struct n = __work_initializer(n, f)

動態:

#define init_work(_work, _func)                                   \

dowhile (0)  

需要編寫工作佇列處理函式:

typedef void (*work_func_t)(struct work_struct *work);
排程工作佇列:

int schedule_work(struct work_struct *work)

int queue_work(struct workqueue_struct *wq, struct work_struct *work)

喚醒工作者佇列執行緒處理。

執行工作者佇列處理程式:

static

int worker_thread(void *__worker)

while

(keep_working(gcwq));

}

可以建立新的工作者佇列和執行緒來處理。平衡是個很關鍵的問題!

Linux 核心學習 6 中斷和異常處理

配置功能選項 中斷流程 連線ioapic引腳的裝置觸發中斷 檢測delivery status是否為0,不是0則等待,否則設其為1 sent pending 將中斷傳送至對應的cpu cpu響應中斷 對於level觸發的中斷,設定irr為1,並等待cpu觸發eoi,再將irr復位0 delivery...

Linux核心學習筆記(五) 系統呼叫

系統呼叫在使用者空間程序和硬體裝置之間新增了乙個中間層。作用 應用程式通過使用者空間實現的應用程式設計介面 api 而不是直接通過系統呼叫來程式設計。unix最流行的應用程式設計介面是基於posix標準的,posix定義的api函式和系統呼叫之間有著直接關係。c庫實現了unix系統的主要api,包括...

linux核心學習筆記

核心的配置 a.make s3c2410 deconfig b.make menuconfig 圖形化配置 c.使用廠家給出的配置 生成.config 編譯生成核心,使用如下命令 make vmlinux make uimage 帶頭部 真正核心 1 config 建立生成autoconf.h 供源...