第8章 下半部和推後執行的工作

2021-08-28 05:53:55 字數 2871 閱讀 2334

8.2 軟中斷

討論從實際的下半部實現——軟中斷方法開始。軟中斷使用得比較少;而tasklet是下半部更常用的一種形式。但是,由於tasklet是通過軟中斷實現的,先來研究軟中斷。

軟中斷的**位於kernel/softirq.c檔案中。

8.2.1 軟中斷的實現

軟中斷是在編譯期間靜態分配的。它不像tasklet能被動地註冊或登出。軟中斷由softirq_action結構表示,定義在中:

/* softirq mask and active fields moved to irq_cpustat_t in

* asm/hardirq.h to get better cache usage.  kao

*/struct softirq_action

;kernel/softirq.c中定義了乙個包含有32個該結構體的陣列:

static struct softirq_action softirq_vec[nr_softirqs] __cacheline_aligned_in_smp;

每個被註冊的軟中斷都佔據該陣列的一項,因此最多可能有32個軟中斷。注意,這是乙個定值——註冊的軟中斷數目的最大值沒法動態改變。在當前版本的核心中,這32個項中只用到9個。

1、軟中斷處理程式

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

void softirq_handler(struct softirq_action *action);

當核心執行乙個軟中斷處理程式時,它就會執行這個action函式,其唯一的引數為指向相應softirq_action結構體的指標。例如,如果my_softirq指向softirq_vec陣列的某項,那麼核心會用如下的方式呼叫軟中斷處理程式中的函式:

my_softirq->action(my_softirq);

乙個軟中斷不會搶占另外乙個軟中斷。實際上,唯一可以搶占軟中斷的是中斷處理程式。不過,其他的軟中斷可以在其他處理器上同時執行。

2、執行軟中斷

乙個註冊的軟中斷必須在被標記後才會執行。這被稱作觸發軟中斷。通常,中斷處理程式會在返回前標記它的軟中斷,使其在稍後執行。於是,在合適的時刻,該軟中斷就會執行。在下列地方,待處理的軟中斷會被檢查和執行:

從乙個硬體中斷**處返回時

在ksoftirqd核心執行緒中

在那些顯式檢查和執行待處理的軟中斷的**中,如網路子系統中

不管是用什麼辦法喚起,軟中斷都要在do_softirq()中執行。如果有待處理的軟中斷,do_softirq()會迴圈遍歷每乙個,呼叫它們的處理程式。

asmlinkage void __do_softirq(void)

rcu_bh_qs(cpu);

}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();

account_system_vtime(current);

_local_bh_enable();

}檢查並執行所有待處理的軟中斷。

8.2.2 使用軟中斷

軟中斷保留給系統中對時間要求最嚴格以及最重要的下半部使用。目前,只有兩個子系統(網路和scsi)直接使用軟中斷。此外,核心定時器和tasklet都是建立在軟中斷上的。tasklet可以動態生成,由於它們對加鎖的要求不高,所以使用起來方便,而且效能也不錯。對於時間要求嚴格並能自己高效地完成加鎖工作的應用,軟中斷是正確的選擇。

1、分配索引

在編譯期間,通過在中定義的乙個列舉型別來靜態地宣告軟中斷。核心用這些從0開始的索引來表示一種相對優先順序。索引號小的軟中斷在索引號大的軟中斷之前執行。

建立乙個新的軟中斷必須在此列舉型別中加入新的項。而加入時,不能簡單地把新項加到列表的末尾。相反,必須根據希望賦予它的優先順序來決定加入的位置。習慣上,hi_softirq通常作為第一項,而rcu_softirq作為最後一項。新項可能插在block_softirq和tasklet_softirq之間。

2、註冊處理程式

在執行時通過呼叫open_softirq()註冊軟中斷處理程式,該函式有兩個引數:軟中斷的索引號和處理函式。軟中斷處理程式執行的時候,允許響應中斷,但它自己不能休眠。在乙個處理程式執行時,當預處理器上的軟中斷被禁止。但其他的處理器仍可以執行別的軟中斷。如果同乙個軟中斷在它被執行的同時再次被觸發了,那麼另外乙個處理器可以同時執行其他處理程式。這意味著任何共享資料都需要嚴格的鎖保護。單純地禁止軟中斷處理程式同時執行不是很理想。如果僅僅通過互斥的加鎖方式來防止它自身的併發執行,那麼使用軟中斷就沒有任何意義了。因此,大部分軟中斷處理程式,都通過採取單處理器資料或其他一些技巧來避免顯式地加鎖,從而提供更出色的效能。

引入軟中斷的主要原因是其可擴充套件性。如果不需要擴充套件到多個處理器,那麼,就使用tasklet。tasklet本質上也是軟中斷,只不過同乙個處理程式的多個例項不能在多個處理器上同時執行。

3、觸發軟中斷

通過在列舉型別的列表中新增新項以及呼叫open_softirq()進行註冊以後,新的軟中斷處理程式就能夠執行。raise_softirq()可以將乙個軟中斷設定為掛起狀態,讓它在下次呼叫do_softirq()時投入執行。

在中斷處理程式中觸發軟中斷是最常見的形式。在這種情況下,中斷處理程式執行硬體裝置的相關操作,然後觸發相應的軟中斷,最後退出。核心在執行完中斷處理程式以後,馬上就會呼叫do_softirq()。於是軟中斷開始執行中斷處理程式留給它去完成的剩餘任務。

第8章 下半部和推後執行的工作

中斷處理程式作為上半部,執行時要麼禁用所有中斷,要麼禁用當前線上的中斷,要麼禁用當前處理機上的同級中斷來保證當前中斷處理的正常執行 下半部用於處理中斷服務的其它任務,允許推後執行,包括軟中斷,tasklet 基於軟中斷 工作佇列 靜態編譯,只有32個軟中斷,目前只用到了9個。靜態結構體陣列中都可含有...

八 下半部和推後執行的工作

中斷處理程式的侷限 1 中斷處理程式以非同步的方式執行,並且它有可能會打斷其他重要 的執行。2 如果當前有乙個中斷處理程式正在執行,最好的情況是,與該中斷同級的其他中斷會被遮蔽,最壞情況下,當預處理器上所有其他中斷都會被遮蔽。3 中斷處理程式往往需要對硬體進行操作,所以他們不能阻塞。這限制了他們所作...

第8章 條件和迴圈 1

8.1 if語句 8.1.1 多重條件表示式 單個if語句可以通過使用布林操作符and or和not實現多重判斷條件或是否定判斷條件。8.1.2 單一語句的 塊 如果乙個復合語句的 塊僅僅包含一行 那麼它可以和前面的語句寫在同一行上。8.2 else語句 8.3 elif 即else if 語句 p...