大內核鎖(BKL)現在已經成為了一個遙遠的記憶,但在那么多年里,它都是內核開發社區面臨的一項棘手問題。然而 BKL 的終結并不意味著內核沒有其他有問題的鎖。近來,已經有一些關注轉向了軟中斷鎖(software-interrupt lock)或“下半部鎖”(bottom half lock),因為它可能會在實時系統上導致延遲。Frederic Weisbecker 正在采取最新行動來減小這個鎖的影響范圍,該方法就是基于移除 BKL 時所采取的方法。
最初,Linux 內核是在單處理器系統上開發的 —— 當然可以理解,因為那時我們手頭只有這種系統 —— 因此,代碼在很大程度上基于這樣的假設:它在 CPU 上運行,完全不存在其他的 CPU。于是 BKL 最終需要被引入,才能讓 Linux 能夠運行在那些產業分析師向我們保證的未來將會大行其道的多處理器機器上。它確保了只有一個 CPU 在任何給定時間內運行內核代碼,從而避免了各種并發問題,但是顯著地犧牲了性能,尤其是隨著 CPU 數量的增加而更加明顯。人們很快意識到 BKL 必須被移除。
在許多子系統中采取的方法是將 BKL 下移至系統的更底層級別。不再是在調用每個驅動程序的 open()函數時就申請持有 BKL,而是修改每個驅動程序來自行獲取 BKL。然后,open()函數可以在不持有 BKL 的情況下安全地得到調用了,每個驅動程序可以在需要時進行獨立的審查(audit)和修復,之后可以刪除其對 BKL 的使用。這種把 BKL 下移的動作將一個大問題分解成了許多較小且更易處理的問題。經過多年的努力,BKL 終于在 2011 年被移除了。
軟中斷(software interrupt)是一種延后執行的方法,用于執行一些是緊急但又無法直接在硬件中斷上下文中執行的工作。當有這種工作要做時,子系統會通過設置一個 flag 來觸發軟中斷;這會使得在下一個合適的時機會調用其處理程序,通常是在硬件中斷處理完成后就立即調用,或在從系統調用返回到用戶空間之前調用。如果處理時間過長,相關處理也可以推送到專門的 ksoftirqd 線程中。
軟中斷有許多使用者,包括 tasklets、網絡、塊設備子系統、讀-拷貝-更新(RCU)以及內核定時器。在某些工作場景中,軟中斷處理可能成為 CPU 總負載的一個重要部分;它可能會運行相當長的時間,從而對運行在用戶空間中的軟件導致延遲。會禁用軟中斷處理的那些內核代碼(為了避免與處理程序的產生 race condition)會變成不可搶占的,這也會導致出現不太愉快的延遲??傊?,與 BKL 一樣,軟中斷反映了幾十年前很適用但是現在存在問題的一種設計。
其中一個設計上的決策是,軟中斷處理程序需要互斥;在任何給定的 CPU 上,只能執行一個軟中斷處理程序。因此,如果塊設備的軟中斷處理程序運行時間很長,那么網絡和定時器處理程序可能就會被無限期地延遲。即使不同類型的軟中斷處理程序之間很少出現競爭,情況仍然是如此。沒有確切的方法可以確定同時運行兩個處理程序是否安全,因此人們不會這樣做。
Weisbecker 的 patch set 旨在通過在定時器子系統中采用 BKL 方式的遷移到更底層實現的方法來解決這個問題。定時器函數會在內核的各個地方被放到隊列里等待調用;它們往往是互相獨立的,與其他軟中斷處理程序并不會產生并發問題。幾乎所有的定時器函數都可以與其他軟中斷處理完全并發地運行 —— 但是這里說的是“幾乎”。在沒有確定每個定時器函數的安全性的情況下,使定時器處理完全獨立于軟中斷處理可能會引入很難調試的問題。
相反,Weisbecker 采取了分成兩步的方法來增加定時器處理的并發性。第一步是允許單個軟中斷向量在不完全禁用軟中斷處理的情況下被禁用。這個 patch set 的目的是允許定時器函數與其他軟中斷并發運行,但它們仍然不會跟彼此并發運行。通過禁用定時器事件的處理(在本地 CPU 上),定時器處理程序可以安全地重新啟用軟中斷處理,而無需擔心會再次調用它。
第二步是允許單個 timer 函數來通知到定時器(timer)子系統,說它們可以跟其他軟中斷處理并發運行。任何不會與軟中斷處理程序競爭、或者在需要時得執行自己的軟中斷禁用代碼的定時器函數,都可以在設置其定時器事件時添加 TIMER_SOFTINTERRUPTIBLE flag 來標記。當定時器子系統看到此標志時,就會在該定時器函數運行時重新啟用軟中斷處理。因此,如果出現更重要的工作的話,這個 timer 函數就可以被搶占。
在 patch set 中只有一個定時器函數 process_timeout()是以這種方式標記的。然而,Weisbecker 期待著“幾年后”的一天內核的所有定時器函數都已經過 audit,并可以安全地與軟中斷處理程序并發運行;在那時,將可以完全從軟中斷機制中移除定時器處理。這樣以來就是朝著最終消除軟中斷的一個小步驟。
顯然,需要進行相當多的工作才能達到這一點。即使這個 patch set 也需要“更多微調”,以使可以中斷的 timer 函數能夠搶占其他軟中斷處理程序,這是解決問題的重要部分。但是,如果這項工作能夠進入 mainline 的話,它可能就能代表著朝著這個方向邁出了一步。Weisbecker 現在已經嘗試了幾次解決軟中斷的問題,但沒有取得太大的成功。然而最終,就像 BKL 一樣,正確的方法將會被找到,長期存在的問題終將得到解決。
審核編輯:劉清
-
處理器
+關注
關注
68文章
19265瀏覽量
229686 -
cpu
+關注
關注
68文章
10855瀏覽量
211615 -
定時器
+關注
關注
23文章
3246瀏覽量
114743 -
LINUX內核
+關注
關注
1文章
316瀏覽量
21645 -
軟中斷
+關注
關注
0文章
8瀏覽量
3030
原文標題:LWN:把軟中斷鎖放到更底層去!
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論