LWN: 5.14 中支持了core scheduling!
關(guān)注了就能看到更多這么棒的文章哦~
Core scheduling lands in 5.14
By Jonathan Corbet
July 1, 2021
DeepL assisted translation
https://lwn.net/Articles/861251/
core scheduling 這個(gè)功能已經(jīng)討論了三年多了。對(duì)于那些需要這個(gè)功能的人來(lái)說(shuō),好消息是終于不用再繼續(xù)等待了。它已經(jīng)被合入了 mainline,會(huì)隨著 5.14 內(nèi)核版本發(fā)布。現(xiàn)在這項(xiàng)工作(可能)已經(jīng)到達(dá)了最終版,我們有必要再看一下這項(xiàng)功能為什么是有意義的、它的工作機(jī)制是什么。core scheduling 功能并不適合每個(gè)人,但它對(duì)一些用戶群體來(lái)說(shuō)已經(jīng)證明是很有用的了。
同步多線程(SMT,simultaneous multithreading,或稱 "超線程,hyperthreading")是一種可以在一個(gè)處理器中實(shí)現(xiàn)兩個(gè)或更多的在執(zhí)行的線程的硬件功能,這樣一來(lái),單個(gè) CPU 看起來(lái)就像是有一組 "sibling(兄弟)" 的 CPU。當(dāng)其中一個(gè)兄弟 CPU 在執(zhí)行時(shí),其他的就必須等待了。SMT 很有用,因?yàn)?CPU 在等待某些 event 時(shí)經(jīng)常會(huì)空閑下來(lái),通常是在等待從內(nèi)存獲取到的數(shù)據(jù)。當(dāng)一個(gè) CPU 在等待時(shí)另一個(gè)就可以執(zhí)行了。SMT 并不是對(duì)所有 workload 的性能都有提升,但對(duì)大多數(shù) workload 來(lái)說(shuō)它都是一個(gè)重大的改進(jìn)。
SMT 中的這些兄弟 CPU 共享了 CPU 內(nèi)部幾乎所有硬件,其中也包括 CPU 在維護(hù)的這些 cache。這就提供了一種可能性,即其中一個(gè) sibling CPU 可以通過(guò)觀察 cache 中可以觀察到的一些變動(dòng),從而提取來(lái)自另一個(gè) sibling CPU 操作的數(shù)據(jù)。Spectre 硬件漏洞使得這個(gè)問(wèn)題變得更加嚴(yán)重了,而且?guī)缀鯖](méi)有辦法解決。要想用目前的內(nèi)核來(lái)安全地運(yùn)行兩個(gè)互不信任的進(jìn)程的話,唯一可靠的辦法就是完全禁用 SMT,這可是很多人(尤其是云計(jì)算供應(yīng)商)明顯感到很不爽的一種做法。
雖然人們可能會(huì)爭(zhēng)辯說(shuō),云計(jì)算供應(yīng)商總是看什么都不滿意,不用去管他們的抱怨。但實(shí)際上如果有辦法能讓他們滿意的話,那就非常有價(jià)值了。其中一種可能性就是允許他們?cè)谧约旱南到y(tǒng)上啟用 SMT,同時(shí)又能避免他們的一些客戶利用其缺陷來(lái)攻擊其他人。只要能相互不信任的進(jìn)程不在同一 CPU core 上同時(shí)運(yùn)行,就可以實(shí)現(xiàn)這個(gè)效果了。云服務(wù)的客戶經(jīng)常同時(shí)有許多進(jìn)程在運(yùn)行(畢竟,大規(guī)模地向互聯(lián)網(wǎng)用戶發(fā)送垃圾郵件就需要很多并發(fā)活動(dòng))。如果這些進(jìn)程可以被限制起來(lái),使得任何一個(gè) CPU core 中的所有 sibling CPU 都只會(huì)運(yùn)行來(lái)自同一客戶的進(jìn)程的話,那么我們就可以避免某個(gè)垃圾郵件發(fā)送者來(lái)竊取另一位垃圾郵件發(fā)送者的客戶列表了,當(dāng)然也會(huì)保護(hù)了其他用戶的私鑰等重要信息。
core scheduling 就可以提供這種隔離。抽象來(lái)說(shuō),每個(gè)進(jìn)程都被分配了一個(gè) "cookie",代表了它的某種特性。比如可以給每個(gè)用戶分配一個(gè)獨(dú)特的 cookie。然后,scheduler 會(huì)確保實(shí)行一條規(guī)則:進(jìn)程只有在具有相同的 cookie 值時(shí)才能共享 SMT core,換句話說(shuō),也就是只有在它們能相互信任的情況下。
更具體地來(lái)說(shuō),core scheduling 是通過(guò) prctl() 系統(tǒng)調(diào)用來(lái)管理的,該系統(tǒng)調(diào)用通常定義如下:
int prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);
在 core-scheduling 這種操作的情況下,option 值為 PR_SCHED_CORE,其余參數(shù)定義為:
int prctl(PR_SCHED_CORE, int cs_command, pid_t pid, enum pid_type type,
unsigned long *cookie);
通過(guò) cs_command 可以選擇四種可能的操作:
PR_SCHED_CORE_CREATE,使內(nèi)核生成一個(gè)新的 cookie,并將其分配給進(jìn)程號(hào)為 pid 的進(jìn)程。type 參數(shù)控制這個(gè)分配動(dòng)作的影響范圍。例如,PIDTYPE_PID 就是指明只改變它所代表的進(jìn)程,而 PIDTYPE_TGID 則將 cookie 分配給整個(gè) thread group 線程組。cookie 參數(shù)的值必須為 NULL。
PR_SCHED_CORE_GET,查找 pid 對(duì)應(yīng)的 cookie 值,將其存放在 cookie 中。注意,用戶空間進(jìn)程就算拿到 cookie 值,也沒(méi)有太多用處,僅僅能夠用來(lái)檢查兩個(gè)進(jìn)程是否有相同的 cookie。
PR_SCHED_CORE_SHARE_TO,將調(diào)用者進(jìn)程的 cookie 值分配給 pid(如上所述,也是使用 type 來(lái)控制影響范圍)。
PR_SCHED_CORE_SHARE_FROM,根據(jù) pid 獲取 cookie 并將其分配給調(diào)用者進(jìn)程。
當(dāng)然,一個(gè)進(jìn)程不能隨意獲取和分配 cookie,這里的判斷條件跟一般人們考慮的 "這個(gè)進(jìn)程能否對(duì)目標(biāo)進(jìn)程調(diào)用 trace() " 的條件差不多。它也不可能在用戶空間生成 cookie 值,這個(gè)限制確保了不相關(guān)的進(jìn)程只會(huì)獲得完全不相同的 cookie 值。內(nèi)核只允許 cookie 值在已經(jīng)有一定程度相互信任的進(jìn)程之間傳播,這樣一來(lái)就可以阻止惡意進(jìn)程將自己的 cookie 改為跟目標(biāo)進(jìn)程一樣的 cookie 值來(lái)進(jìn)行攻擊了。
每當(dāng)一個(gè) CPU 來(lái)執(zhí)行 scheduler 代碼時(shí),會(huì)先挑出最高優(yōu)先級(jí)的任務(wù),按正常方式運(yùn)行。如果 core scheduling 啟用了,那么接下來(lái)就會(huì)向 sibling CPU 發(fā)送一個(gè) IPI 中斷(inter-processor interrupt),每個(gè) sibling CPU 就會(huì)相應(yīng)地來(lái)檢查這個(gè)剛剛得到調(diào)度的進(jìn)程的 cookie 值與本地已經(jīng)在運(yùn)行進(jìn)程的 cookie 值是否相等。如果有必要的話,被中斷打斷的 CPU 就會(huì)切換到另一個(gè)擁有相同 cookie 的進(jìn)程去執(zhí)行,即使當(dāng)前正在運(yùn)行的進(jìn)程具有更高的優(yōu)先級(jí)也不影響這個(gè)結(jié)果。如果沒(méi)有能互相信任的其他進(jìn)程,那么這個(gè) sibling CPU 就直接閑置下來(lái),直到情況發(fā)生變化為止。如果可能的話,scheduler 會(huì)在各個(gè) CPU 之間遷移進(jìn)程來(lái)避免這個(gè) sibling CPU 被強(qiáng)制空閑下來(lái)。
core scheduling 早期 patch 中的內(nèi)核調(diào)度代碼對(duì)整個(gè)系統(tǒng)來(lái)說(shuō)會(huì)引起很大的開(kāi)銷。有時(shí)測(cè)出來(lái)甚至比完全禁用 SMT 更糟糕,這就違反了本來(lái)的目標(biāo)了。不過(guò),在那之后這部分代碼已經(jīng)經(jīng)歷了多次修訂,現(xiàn)在顯然表現(xiàn)得更好了。不過(guò),畢竟這個(gè)機(jī)制在極端情況下會(huì)導(dǎo)致 CPU 明明有進(jìn)程等著執(zhí)行的情況下也會(huì)被閑置,因此這個(gè)方案總是會(huì)有代價(jià)的。由于這個(gè)原因,Linus Torvalds 也說(shuō) core scheduling "對(duì)大多數(shù)人來(lái)說(shuō)基本沒(méi)有意義"。不過(guò),針對(duì)那些必須要關(guān)閉 SMT 不可的情況下,現(xiàn)在這個(gè)替代方案很可能是有好處的。
雖然,安全相關(guān)的使用場(chǎng)景在推動(dòng) core scheduling 的開(kāi)發(fā),但其實(shí)也有其他的場(chǎng)景也迫切希望能擁有這個(gè)功能。例如,運(yùn)行實(shí)時(shí)進(jìn)程的系統(tǒng)通常必須要禁用 SMT,因?yàn)楫?dāng) CPU 在需要跟 sibling CPU 爭(zhēng)奪硬件資源時(shí),完全無(wú)法保證這個(gè) response-time。core-scheduling 可以確保實(shí)時(shí)進(jìn)程會(huì)獨(dú)立擁有一個(gè) CPU,同時(shí)系統(tǒng)的其他部分可以繼續(xù)使用 SMT。還有其他情況一些情況也需要這種能控制同一 CPU 上的進(jìn)程是否可以混合著運(yùn)行的能力。
因此,盡管 core scheduling 對(duì)大多數(shù) Linux 用戶來(lái)說(shuō)可能并沒(méi)有什么用處,但還是有一些用戶團(tuán)體會(huì)很高興看到這個(gè)功能最終進(jìn)入了 mainline。對(duì)類似 scheduler 這樣的核心、性能敏感的組件上添加這種復(fù)雜的邏輯,從來(lái)就不是一件容易的事情。但是,只要有足夠的決心總能找到辦法。參與到這個(gè)功能的開(kāi)發(fā)中的開(kāi)發(fā)者們肯定為推動(dòng)這項(xiàng)工作的成功完成而得到了應(yīng)有的 cookie。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長(zhǎng)按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開(kāi)源社區(qū)的各種新近言論~
