作業系統核心

核心搶占(kernel preemption)

搶占是排程器強制把 CPU 從執行中的工作奪走、去跑一個更該跑的工作的能力,而不是等那個工作自願放棄。核心搶占探討的是:這件事是否能在一個工作正在核心裡執行時——也就是系統呼叫或核心工作進行到一半時——發生。這個答案形塑了系統的回應手感:若一個低優先順序的工作正深陷某個核心常式,而一個高優先順序的工作醒來,核心能否就在那一刻搶走 CPU,還是必須等到那個核心常式結束?

這裡有一條光譜。在不可搶占的核心裡,工作一旦進入核心,便在那裡執行直到它阻塞或返回使用者空間——一個醒來的高優先順序工作必須等待,這增加延遲。自願搶占加入檢查點:核心在各處撒下一些位置,若有更高優先順序的工作在等,目前的工作便自願讓步——這是個降低延遲又不全面增加複雜度的折衷。一個完全可搶占的核心,允許排程器在幾乎任何一點搶占核心程式碼(除了明確停用搶占的臨界區間之內,例如持有自旋鎖時),給出最低的延遲,這對即時與互動的工作負載最為重要。這也是為何持有自旋鎖的程式碼會停用搶占:它不可在臨界區間中途被排程走。

一段照亮這個設計的歷史:早期 Linux 的多處理器支援用一把單一的大核心鎖(BKL)——一把巨大的鎖,本質上一次只讓一個 CPU 執行核心程式碼。它簡單又正確,卻是個糟糕的可擴展性瓶頸,因為它把整個核心串列化了。Linux 開發那條漫長、辛苦的征途,就是把那一把鎖換成細粒度鎖(許多保護個別資料結構的小鎖),並使核心可搶占,使多個核心能並行執行核心程式碼、高優先順序的工作不必等待。BKL 終於在 2011 年被完全移除。教訓是:「一把大鎖」是簡單而慢的答案,真正的可擴展性來自小心地把它拆開——驅動自旋鎖、RCU 與每 CPU 資料的,正是同一個教訓。

低優先順序工作在系統呼叫途中;一個高優先順序工作醒來。不可搶占:它等到系統呼叫結束。完全可搶占:排程器就在此刻搶占核心(除非搶占被停用,例如在自旋鎖下)。

可搶占的核心能為高優先順序工作立刻從核心程式碼奪走 CPU,降低延遲——除了刻意停用搶占之處。

歷史上的大核心鎖正確卻對擴展是場災難,因為它把整個核心串列化了;漫長的修補是細粒度鎖加上搶占,在 2011 年移除 BKL 時完成。普遍的教訓:一把大鎖簡單而慢——可擴展性來自把它拆開,這正是自旋鎖、RCU 與每 CPU 資料存在的原因。

又称
preemptible kernelvoluntary preemptionBig Kernel Lock (BKL)可搶占核心大核心鎖