linux中斷處理的核心:頂半部和底半部
裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。
為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間找到乙個平衡點,linux將中斷處理程式分解為兩個半部:頂半部(op half)和底半部(bottom half)。
頂半部完成盡可能少的比較緊急的功能,它往往只是簡單地讀取暫存器中的中斷狀態並清除中斷標誌後就進行「登記中斷」的工作。「登記中斷」意味著將底半部處理程式掛到該裝置的底半部執行佇列中去。
這樣,頂半部執行的速度就會很快,可以服務更多的中斷請求。現在,中斷處理工作的重心就落在了底半部的頭上,它來完成中斷事件的絕大多數任務。底半部幾乎做了中斷處理程式所有的事情,而且可以被新的中斷打斷,這也是底半部和頂半部的最大不同,因為頂半部往往被設計成不可中斷。底半部則相對來說並不是非常緊急的,而且相對比較耗時,不在硬體中斷服務程式中執行。
頂半部是實際響應中斷的過程,也就是用request_irq註冊的中斷例程。而底半部會在稍後比較安全的時間內執行的過程。即底半部的中斷都是開啟的。比較典型的情況是頂半部儲存裝置的資料到乙個裝置特定的快取區並排程它的底半部,然後退出;這個過程是非常迅速的。然後底半部執行其他必要的工作,例如喚醒程序、啟動另外的i/o操作等等。這種方法允許在底半部工作期間,頂半部還可以繼續為新的中斷服務。
儘管頂半部、底半部的結合能夠改善系統的響應能力,但是,僵化地認為 linux裝置驅動中的中斷處理一定要分兩個半部則是不對的。如果中斷要處理的工作本身很少,則完全可以直接在頂半部全部完成。其他作業系統中對中斷的處理也採用了類似於linux系統的方法,真正的硬體中斷服務程式都應該盡可能短。因此,許多作業系統都提供了中斷上下文和非中斷上下文相結合的機制,將中斷的耗時工作保留到非中斷上下文去執行。
linux 系統實現底半部的機制主要有tasklet,工作佇列和軟中斷。linux 的中斷處理分為兩個半部,頂半部處理緊急的硬體操作,底半部處理不緊急的耗時操作。tasklet和工作佇列都是排程中斷底半部的良好機制,tasklet基於軟中斷實現。核心定時器也依靠軟中斷實現。核心中的延時是忙等待或者睡眠等待,為了充分利用cpu資源,使系統有更好的吞吐效能,在對延遲時間的要求並不是很精確的情況下,睡眠等待通常是值得推薦的。
那頂半部和底半部表現在**中到底是乙個什麼情況呢?我的理解是在中斷中排程工作佇列(或者其他機制)中的某個工作和執行一些簡單的**(這個稱為頂部),然後中斷就結束了,以確保中斷的高吞吐率,那中斷具體要執行的事情當然就有工作佇列中的任務去完成了(這個稱為底部)。
Linux 中斷處理的核心 頂半部和底半部
裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間找到...
Linux裝置驅動程式 中斷處理之頂半部和底半部
裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間找到...
linux中斷處理的上半部和下半部
裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必 要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能 要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間...