linux的內核搶占


  一篇博文,未細考證,貼來學習。也可以參考LKD 4.6節

  早期的Linux內核是不可搶占的。它的調度方法是:一個進程可以通過schedule()函數自願地啟動一次調度。非自願的強制性調度只能發生在每次從系統調用返回的前夕以及每次從中斷或異常處理返回到用戶空間的前夕(這種強制性調度又叫用戶搶占)。但是,如果在系統空間發生中斷或異常是不會引起調度的。這種方式使內核實現得以簡化。但常存在下面兩個問題:

  • 如果這樣的中斷發生在內核中,本次中斷返回是不會引起調度的,而要到最初使CPU從用戶空間進入內核空間的那次系統調用或中斷(異常)返回時才會發生調度。
  • 另外一個問題是優先級反轉。在Linux中,在核心態運行的任何操作都要優先於用戶態進程,這就有可能導致優先級反轉問題的出現。例如,一個低優先級的用戶進程由於執行軟/硬中斷等原因而導致一個高優先級的任務得不到及時響應。

當前的Linux內核加入了內核搶占(preempt)機制。內核搶占指用戶程序在執行系統調用期間可以被搶占,該進程暫時掛起,使新喚醒的高優先級進程能夠運行。這種搶占並非可以在內核中任意位置都能安全進行,比如在臨界區中的代碼就不能發生搶占。臨界區是指同一時間內不可以有超過一個進程在其中執行的指令序列。在Linux內核中這些部分需要用自旋鎖保護。

內核搶占要求內核中所有可能為一個以上進程共享的變量和數據結構就都要通過互斥機制加以保護,或者說都要放在臨界區中。在搶占式內核中,認為如果內核不是在一個中斷處理程序中,並且不在被 spinlock等互斥機制保護的臨界代碼中,就認為可以"安全"地進行進程切換。

Linux內核將臨界代碼都加了互斥機制進行保護,同時,還在運行時間過長的代碼路徑上插入調度檢查點,打斷過長的執行路徑,這樣,任務可快速切換進程狀態,也為內核搶占做好了准備。

Linux內核搶占只有在內核正在執行例外處理程序(通常指系統調用)並且允許內核搶占時,才能進行搶占內核。禁止內核搶占的情況列出如下:

(1)內核執行中斷處理例程時不允許內核搶占,中斷返回時再執行內核搶占。

(2)當內核執行軟中斷或tasklet時,禁止內核搶占,軟中斷返回時再執行內核搶占。

(3)在臨界區禁止內核搶占,臨界區保護函數通過搶占計數宏控制搶占,計數大於0,表示禁止內核搶占。

搶占式內核實現的原理是在釋放自旋鎖時或從中斷返回時,如果當前執行進程的 need_resched被標記,則進行搶占式調度

 

詳細背景和實現:http://blog.csdn.net/sailor_8318/article/details/2870184


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM