Linux 中斷處理的核心 頂半部和底半部

2021-06-23 09:46:37 字數 2450 閱讀 7428

裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。 

為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間找到乙個平衡點,linux 將中斷處理程式分解為兩個半部:頂半部(top  half)和底半部(bottom half)。

頂半部完成盡可能少的比較緊急的功能,它往往只是簡單地讀取暫存器中的中斷狀態並清除

中斷標誌後就進行「登記中斷」的工作。「登記中斷」意味著將底半部處理程式掛到該裝置的底半部執行佇列中去。這樣,頂半部執行的速度就會很快,可以服務更多的中斷請求。現在,中斷處理工作的重心就落在了底半部的頭上,它來完成中斷事件的絕大多數任務。底半部

幾乎做了中斷處理程式所有的事情,而且可以被新的中斷打斷,這也是底半部和頂半部的最大不同,因為頂半部往往被設計成不可中斷。底半部則相對來說並不是非常緊急的,而且相對比較耗時,不在硬體中斷服務程式中執行。

頂半部是實際響應中斷的過程,也就是用request_irq註冊的中斷例程。而底半部會在稍後比較安全的時間內執行的過程。即底半部的中斷都是開啟的。比較典型的情況是頂半部儲存裝置的資料到乙個裝置特定的快取區並排程它的底半部,然後退出;這個過程是非常迅速的。然後底半部執行其他必要的工作,例如喚醒程序、啟動另外的i/o操作等等。這種方法允許在底半部工作期間,頂半部還可以繼續為新的中斷服務。

儘管頂半部、底半部的結合能夠改善系統的響應能力,但是,僵化地認為 linux裝置驅動中的中斷處理一定要分兩個半部則是不對的。如果中斷要處理的工作本身很少,則完全可以直接在頂半部全部完成。其他作業系統中對中斷的處理也採用了類似於linux系統的方法,真正的硬體中斷服務程式都應該盡可能短。因此,許多作業系統都提供了中斷上下文和非中斷上下文相結合的機制,將中斷的耗時工作保留到非中斷上下文去執行。 

linux 系統實現底半部的機制主要有tasklet,工作佇列和軟中斷。linux 的中斷處理分為兩個半部,頂半部處理緊急的硬體操作,底半部處理不緊急的耗時操作。tasklet 和工作佇列都是排程中斷底半部的良好機制,tasklet 基於軟中斷實現。核心定時器也依靠軟中斷實現。核心中的延時是忙等待或者睡眠等待,為了充分利用cpu資源,使系統有更好的吞吐效能,在對延遲時間的要求並不是很精確的情況下,睡眠等待通常是值得推薦的。

(1) tasklet (首選機制),它非常快, 但是所有的 tasklet **必須是原子的;始終工作在中斷期間執行。

(2)工作佇列, 它可能有更高的延時,但允許休眠。工作在乙個特殊核心程序的上下文中執行。

14.3  linux 中斷處理的核心:頂半部和底半部

中國有句俗話:魚與熊掌不可兼得。這句話也充分體現在了中斷處理上。在一定的時間內完成的工作量和工作的複雜程度往往是對立的。也就是說,如果想在1小時內做很多任務作,那麼每項工作就不能太複雜,否則不可能完成任務。中斷處理也是一樣。核心在處理中斷請求時要求在單位時間內處理盡可能多的中斷,也就是說要求處理中斷的吞吐率要盡可能地大。這就要求中斷處理函式中的**盡可能地短小,而且不能有耗時的操作。但這往往很不現實。事實上,大多數中斷處理程式是很複雜的,也不是在很短的時間就可以執行完的。為了解決這個問題,核心設計者將中斷處理分為兩個階段,也就是我們常說的頂半部(top half)和底半部(bottom half)。通過頂半部和底半部,可以在某種程度上緩解魚與熊掌不可兼得的問題。

處理中斷可以分為如下兩部分。

接收和響應中斷請求。

處理中斷的業務邏輯。

一般複雜的工作都在處理中斷的業務邏輯中。而接收和響應中斷請求會在很短的時間被處理完。根據這兩項工作所需的時間差異,很容易想到可以同步來執行中斷請求的接收和響應,而通過非同步的方式執行耗時比較多的操作,也就是處理中斷的業務邏輯。

我們在編寫服務端網路程式時往往會開啟乙個監聽執行緒來接收客戶端的請求。一旦接收到某個客戶端的請求,一般不會直接在監聽執行緒中處理客戶端的請求,而是再開啟乙個專門處理客戶端請求的執行緒,並在該執行緒中處理客戶端的請求。這樣監聽執行緒就可以解脫出來處理更多的客戶端請求,從而大大提高服務端程式的吞吐量。

中斷處理程式和服務端網路程式類似,當硬體向核心傳送中斷請求時,核心(在這裡核心就相當於服務端網路程式)首先會接收中斷請求,這個接收中斷請求的任務就是由中斷處理程式的頂半部完成的。然而在頂半部中並不會執行中斷處理的核心**,而這些**需要在底半部完成。對於頂半部來說,除了接收中斷請求外,還會進行"登記工作"。也就是說要將底半部處理程式掛到傳送中斷請求的裝置的底半部執行佇列中。這樣的安排,頂半部的執行速度就會很快,可以服務更多的中斷請求。

現在,中斷處理工作的重心已經落在了底半部的頭上,由底半部來完成中斷處理的大部分工作。底半部幾乎做了中斷處理程式所有的事情,而且可以被新的中斷打斷,這也是底半部和頂半部的最大不同,因為頂半部不能被其他中斷打斷。底半部則相對來說並不是非常緊急的,而且相對比較耗時,並且不在硬體中斷服務程式中執行。

儘管中斷處理可以通過頂半部和底半部的結合來改善系統的響應能力,但是在實際的應用中並不一定要分兩個半部來處理。如果處理中斷的任務很小,耗時比較短,完全可以直接在頂半部完成,根本就不需要底半部的參與。

Linux 中斷處理的核心 頂半部和底半部

linux中斷處理的核心 頂半部和底半部 裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。為了在中斷執行時...

Linux裝置驅動程式 中斷處理之頂半部和底半部

裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間找到...

linux中斷處理的上半部和下半部

裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必 要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能 要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間...