下半部機制之軟中斷

2021-06-05 19:33:07 字數 3496 閱讀 4499

軟中斷(softirq)是用軟體方式模擬硬體中斷的概念,實現巨集觀上的非同步執行效果。softirq是基本的下半部機制,需要互斥使用。一般很少直接使用。通常只用在少數效能比較關鍵的子系統中。它是可重入的,允許乙個softirq的不同例項可同時執行在不同的處理器上。軟中斷的**位於kernel/softirq.c。

軟中斷在編譯時靜態分配,不能動態註冊和銷毀。軟中斷一般用sofirq_action結構來表示,定義在中:

struct softirq_action ;

乙個具有32個元素的結構陣列宣告在kernel/softirq.c中:

static struct softirq_action softirq_vec[nr_softirqs];

每個註冊的軟中斷佔據陣列的一項,因此,總共有nr_softirqs個註冊的軟中斷。軟中斷的數目是在編譯時靜態決定的,不能動態更改。核心中軟中斷個數的限制是32個,但在當前核心中,只有9個。

軟中斷處理函式

軟中斷處理函式原型如下:

void softirq_handler(struct softirq_action *)

軟中斷不會搶占另乙個軟中斷,只有中斷處理函式才能搶占乙個軟中斷。

軟中斷一般用於處理系統中對時間最苛刻和重要的後半部**。當前,只有兩個子系統直接使用了軟中斷:網路子系統和塊裝置子系統。另外核心計時器和微執行緒都基於軟中斷之上。

執行軟中斷

乙個註冊的軟中斷必須被標記後,才能執行。這稱之為觸發,實質上就是將其標記為未決狀態。通常,中斷處理函式會觸發乙個軟中斷,然後返回。在合適的時間,軟中斷會執行。

檢測未決狀態下的軟中斷通常發生在如下幾個地方:

執行軟中斷的**主要發生在函式__do_softirq()函式中,由do_softirq()呼叫。主要**如下:

u32 pending; 

pending = local_softirq_pending();

if (pending) while (pending);

}

其基本步驟如下:

1.設定本地變數pending的值為巨集local_softirq_pending()返回的值。它是乙個32位掩碼,如果第n位置1,表示第n個軟中斷處於未決狀態。

2.清空掩碼。

3.指標h被置為softirq_vec的第一項。

4.如果pending的第一位置位,呼叫h->action(h)。

5.遞增指標h,使其指向softirq_vec陣列的第二項。

6.掩碼pending右移一位。

7.pointer現在指向陣列的第二項,pending掩碼的第乙個位元位就是原來的第二個位元位,重複前述步驟。

8.重複執行,直到pending為0。

使用軟中斷

在宣告乙個軟中斷時,用到了軟中斷的索引號,它是乙個列舉型別,定義在中。核心使用該索引來作為軟中斷的相對優先順序。值越小,優先順序越大。建立乙個新的軟中斷時,就包括向該列舉型別新增乙個新的項。

tasklet

priority

softirq description

hi_softirq 0

high-priority tasklets

timer_softirq 1

timers

net_tx_softirq 2

send network packets

net_rx_softirq 3

receive network packets

block_softirq 4

block devices

tasklet_softirq 5

normal priority tasklets

sched_softirq 6

scheduler

hrtimer_softirq 7

high-resolution timers

rcu_softirq 8

rcu locking

註冊軟中斷處理函式

使用open_softirq()函式可以註冊軟中斷對應的處理函式,如下例子所示:

open_softirq(net_tx_softirq, net_tx_action);

open_softirq(net_rx_softirq, net_rx_action);

軟中斷處理函式處於中斷上下文中,且所有其他的中斷是使能的,不能休眠。當乙個軟中斷處理函式執行時,當預處理器的軟中斷被禁用。但是,另外乙個處理器可以執行其他的軟中斷。如果在執行的過程中,觸發了相同的軟中斷,另乙個處理器可以同時執行它。這意味著,只在軟中斷處理函式中使用的任何其享的資料或全域性資料需要進行適當的鎖定。這是很重要的一點,也就是為什麼盡量使用微執行緒的原因了。僅僅防止軟中斷不同步執行並不理想。如果乙個軟中斷獲得了阻止其本身的另乙個例項同步執行的鎖,就沒有任何理由使用軟中斷了。結果,大部分軟中斷處理函式使用每-處理器資料或其他的技巧以避免顯示地使用互斥鎖。

觸發軟中斷

當乙個軟中斷處理函式通過open_softirq()加入到列舉列表後,它就可以執行了。呼叫函式raise_softirq()就行了,如下所示:

raise_softirq(net_tx_softirq);

該函式首先會在觸發軟中斷之前禁用所有中斷,之後將它們恢復成之前的狀態。如果所有的中斷已經關閉,可以使用另外乙個函式:raise_softirq_irqoff(),如下所示:

/*

* interrupts must already be off!

*/raise_softirq_irqoff(net_tx_softirq);

softirq使用模板:

usingsoftirq tooffload workfrom interrupthandlers

void__init

roller_init()

/*the bottomhalf */

void

roller_analyze()

/*the interrupthandler */

staticirqreturn_t

roller_interrupt(intirq, void*dev_id)

下半部之軟中斷和tasklet

由中斷和異常的區別可知,中斷處理程式以一部方式執行,並且他有可能會打斷其他重要 甚至包括其他中斷處理程式 的執行。因此為了避免被打斷的 停止時間過長,中斷處理程式應該執行得越快越好。中斷處理程式不再程序上下文中執行,所以他們不能阻塞,所以他們有很高的的實現要求。作業系統個必須有乙個快速 非同步 簡單...

中斷管理之下半部軟中斷

linux中斷管理中有個非常重要的設計理念就是上下半部機制 上半部就是硬體中斷管理 中斷設計為上下半部的原因如下 1.硬體中斷處理程式以非同步方式進行 它會打斷其他重要的 執行 因此為了避免被打斷的程式停止時間太長 硬體中斷處理程式必須盡快完成 2.硬體中斷處理程式通常在關閉中斷的情況下執行 關閉中...

例項 中斷的下半部分之 軟中斷

在linux中斷加入自已的軟中斷 軟硬體環境 linux 2.6.36 s3c2440 步驟如下 在軟中斷定義的列舉型別列表中加入自已的軟中斷號my softirq 具體到linux 2.6.36 include linux interrupt.h的第376行的列舉列表。其中已經有10項,在nr s...