1 Linux內(nèi)核開發(fā)模式
宏觀上說一下內(nèi)核的開發(fā)模式,還有 Linux 6.2 整體的大概是什么情況。這里包括自己跟著寫代碼之外,還包括對于規(guī)范的理解,還包括跟社區(qū)的溝通。
一般來說,參與社區(qū)不是單單一個動作,對內(nèi)核來說其實也是一樣的。即使你說編譯器,它可能也不是一個社區(qū),包括 RISC-V 它雖然是一個架構(gòu),但它其實里面又有不同的工作組,這里面其實還有挺多溝通的事情。寫代碼是一部分的工作,大家如果去關(guān)注內(nèi)核的時候,如果對于內(nèi)核的開發(fā)模式有一個了解的話,會對于關(guān)注內(nèi)核的動態(tài)會有一些幫助。
從這個圖中能看到一些,我們?nèi)绻腙P(guān)注一些內(nèi)核的動態(tài),能從這些點去關(guān)注。
1.1提交郵件列表
普通軟件開發(fā)流程很簡單,我們一般寫代碼 Review 合進去,一般軟件開發(fā)就這么做。而內(nèi)核開發(fā)其實很類似,假設(shè)已經(jīng)都落到特性上(就不說前面特性怎么定出來的),我們要開發(fā)一個特性了,開發(fā)之后發(fā)內(nèi)核社區(qū)還是比較 old school 的,它是通過發(fā)郵件的方式發(fā)到郵件列表 ,然后大家都可以 Review 。
最終是看 maintainer有沒有給你 acknowledgment(ACK) ,給你 ACK之后補丁就有機會合進去,最終評審這部分最終的目標其實就是沒有人反對,并且你所修改的子系統(tǒng)的這部分(比如 arch/arm64 的或者內(nèi)存子系統(tǒng),或者是 RISC-V),能給你一個 ACK,所以 ack by xxx 就過了,然而 Review 過了以后并不會直接合進去。
1.2合入Next分支
在平時比較簡單開發(fā)流程,評審過之后可能跑個CI,通過后可能就合進去了。但是對于內(nèi)核來說,它其實不會直接合進去。為啥呢?因為內(nèi)核補丁太多了,其實每一次的大版本內(nèi)核的合入可能都是上萬個提交。這么多個補丁,如果評審之后一把就合了主線,大家就很難拿到一個相對比較穩(wěn)定的主線去做開發(fā)。所以用了一個折中的方式,先合入到每個子系統(tǒng)的分支(比如我們?nèi)ズ先氲?arch/arm64 子系統(tǒng)的分支里面,或者合入這個內(nèi)存的子系統(tǒng)),或者文件系統(tǒng)的一個 next分支。
什么是 next分支?next分支是在下一次內(nèi)核大版本開發(fā)時,補丁有機會被合進的分支,所以叫 next分支。如果你的補丁過 Review 就會合到 next分支。這種情況下, 對于一般的特性來說就比較穩(wěn)了,到了 next分支,在下一版大版本開發(fā)的時候,你就有機會被推到主線。當(dāng)然個別情況也有可能你進next分支之后,進主線的時候被其他人叫過來 “哎這個東西我不同意”,一般比較資深的 maintainer 可能會跳出來了,你的補丁有可能會被踢出去。一般是改得比較深的比較多的補丁上會有這個可能。假如沒有反對意見,其實最終會合到主分支。
1.3合入窗口(merge window)
平時開發(fā)的補丁要合入主線,往往是一直可以(除非是要 freeze,否則一般可以一直合入的)。但是對于內(nèi)核來說,補丁其實并不是一直可以合入的,對于一個大特性來說,真正能合入的時間叫 merge window,就是合入窗口。對于每一個內(nèi)核來說,其實都只有兩周的合入窗口。比如現(xiàn)在 6.2 內(nèi)核大概是在 10 ~ 8 周之前開了兩周的 merge window,然后只有在兩周的 merge window 期間才能夠合入大特性。
在 merge window 干什么事?其實這些代碼會被各子系統(tǒng) maintainer會發(fā)一個 request(比如 arch/arm64 或者是內(nèi)存子系統(tǒng)),請求 Linus 去合入。如果 Linus 沒意見,就會合到主分支。可能你經(jīng)常看到 Linus 噴補丁,有的時候是在 Review 階段,有的時候是在兩周的 merge window 期間(next分支往里推的時候)。
1.4合入主線(master)
如果能夠進主分支,通常來說問題不大了。但是也不排除在后面的大版本的測試過程中,或者由于一些人的反對或者測試確實出現(xiàn)了一些性能下降或者重大的問題,也有可能補丁會再被踢出來。
合到主分支之后,測試時間對 Linux 來說是有 7~8周 的 release candidate 。在這個過程里,可以合入一些 bugfix,補丁也是可以通過 RC 合進去的,但如果是更大的修改,可能 RC 就合不進去了。
1.5評估補丁合入的時間
可能經(jīng)常你會看到,某某公司的某個特性,預(yù)計什么版本會合入。怎么能預(yù)計呢?因為他說補丁已經(jīng)進了某個子系統(tǒng)的 next分支,它一旦進 next分支后,可以知道在下一個大版本里面,它就有可能會被合進去。所以他大概也可以這樣講,但也有可能正好沒進去。
包括大家前面有提到 Rust,其實前面會有好幾次說 Rust 要合一些代碼,你發(fā)現(xiàn)好像沒怎么合進去,因為這個東西改的確實比較多,所以有時候會有些爭議。
1.6進入staging分支
這是一個比較順的路線,你最終合進去了,是一個比較好的結(jié)局。這個過程也比較崎嶇,因為你從補丁開發(fā)開始,可能要經(jīng)過一兩年的時間才會合進去。但也有可能事情不順,評審之后你發(fā)現(xiàn)補丁可能進不去,但是好像又沒直接給你拍死,在驅(qū)動里面比較多見。就還會進入到一個 staging分支里。
staging 什么意思呢?這個東西暫時還不符合要求,但是你如果愿意再搞一搞,其實也可以再進去。我前面自我介紹里有寫叫 ilp32,當(dāng)時也搞好長時間,跟Cavium公司一起搞,最后也沒合入主線就在 standing分支里飄,飄了一年多還是沒進去,也是一個悲傷的故事。
1.7了解內(nèi)核動態(tài)的方式
每個階段都可以是我們?nèi)チ私鈨?nèi)核動態(tài)的方式。比如在補丁 Review 的時候,我們可以通過郵件列表,看說這個人是在討論什么,有哪些補丁在討論。你能看到他們是怎么討論的?;緛碚f,你去看一些討論,你大概知道他最近可能關(guān)注點是什么,他可能對于補丁的合作要求大概是什么,你大概知道怎么回事了。后面不管你自己問問題還是寫補丁的時候,可能會做更有針對性一點,但這個方式對你要求有點高,要求你對這個部分確實比較熟悉。
比如像我是做 ARM 的,但我想關(guān)注那塊動態(tài),但我并不想很深入地去看,我還可以在哪看呢?我想大概知道他什么時候可能會進,我可以在 next分支看一下,我會看一看這個模塊或者子系統(tǒng),當(dāng)前的 next分支做到什么程度。我可以基本上認為 next分支的代碼會在未來的幾周之內(nèi)進到 master分支的。但如果你連這個都不想知道,你只想知道真正進了 master分支,那其實就在每個內(nèi)核開發(fā)的 merge window 之后。但如果你連這個都不想知道,你最后看 release 結(jié)果也可以。
這部分內(nèi)核開發(fā)流程還可以參考內(nèi)核文檔,并且這部分已經(jīng)有了中文翻譯:https://gitee.com/mirrors/linux_old1/blob/master/Documentation/translations/zh_CN/process/2.Process.rst
2 Linux 6.2整體情況
我來之前順便看了一下6.2 內(nèi)核的整體情況,除了合并記錄之外大概是有 13000 多個提交。
2.1提交按作者看提交數(shù)量
靠前的作者里大概有兩種,一種是像 Linus、Thomas 和 Arnd ,包括 Mark Brown,他們其實都是 maintainer(某個子系統(tǒng)或者內(nèi)核 maintainer) ,所以當(dāng)我按作者查詢的時候可以看到他們的名字的;還有一種情況是因為代碼重構(gòu)或硬件支持或修復(fù)一些簡單的錯誤(做大特性,一個補丁一次也很難合入這么多補丁的)。`
來自pengutronix.de的Uwe Kleine-K?nig的補丁基本是把不需要傳入i2c設(shè)備id的枚舉(probe)替換為新的接口(probe_new)。probe_new不需要傳入設(shè)備id。API的修改來自:“Stephen Kitt steve@sk2.org”提交的“bf08ce132cd0 drivers/gpio: use simplei2c probe”。
Linaro的Krzysztof Koz?owski,主要是做一些設(shè)備樹的binding和小問題的修改。比如像Linaro是做 ARM 生態(tài)的組織(因為ARM是一個公司,它不像RISC-V本來就是一個偏社區(qū)型的東西,當(dāng)時 ARM 跟幾個公司一起專門去做ARM生態(tài)一個組織,叫Linaro`)。
還有一種情況是它可能在蓄謀做更大的事情,在過程里面有很多小事情要干。比如之前有人專門噴過華為這個事,為什么華為總會有工程師去發(fā)一些很簡單的補丁,其實他們在做一個內(nèi)核維測的工具。
2.2按郵箱后綴看提交數(shù)量
按郵箱后綴大概是這么個排名。為什么按郵箱后綴呢?因為像 kernel.org,gmail,包括 Linaro,背后其實可能都會歸到一些公司里面,所以我們不好講是哪個公司里面的。Linaro 有兩種,一種是 linaro.org 是 Linaro 自己的員工,另一種是其他各公司員工發(fā)布的是否也會用 linaro.org 后綴( Linaro 是一個社區(qū)的組織)。
我們看到這里有幾種人,一種是像 Linaro 這種做社區(qū)的;還有一種軟硬件方案都做,像 Intel 、nvidia 和 華為;還有一種像 redhat和 suse,他們都是做發(fā)行版的。
3 Linux 6.2在體系結(jié)構(gòu)的更新
說到稍微具體點的技術(shù),因為我自己在做工作中,包括學(xué)習(xí),去接觸 ARM架構(gòu)的時候,其實我能明顯感覺到,首先它這東西挺多的,而且有的時候確實有些問題不太好調(diào),同時它有一些相對比較基本的內(nèi)容。
哪些內(nèi)容比較基本?對任何一個架構(gòu)來說,其實我們有三方面的內(nèi)容一定要先搞清楚。第一方面是軟硬件接口(就是匯編語言),第二方面是異常怎么去處理,第三方面是內(nèi)存怎么管的。把這三個東西搞清楚,大多數(shù)特性都是從這三個東西長出來的。如果你這三個東西沒搞清楚,有些時候看一些東西你就覺得好像是這么回事,但是它背后的邏輯你可能搞不清楚。所以我們順便也借這個東西稍微提一下。
3.1 ARM64的shadow stack代碼的歸一,可以同時支持PAC和非PAC的情況
PAC 是什么? PAC 其實是一個指針認證的能力,它其實在看指針訪問是不是合法的一個東西。為什么 ARM架構(gòu)上面能有 PAC 的特性?因為在 ARM64 里面其實只有一位是真正起到內(nèi)核空間跟用戶空間劃分作用(我們所見的 ARM64 地址空間,用戶空間是若干個 0 開頭的,內(nèi)核空間是若干個 1 開頭)。比如我是 52BIT 地址空間,BIT63-BIT52 并不是都是要都置成 0 或者 1 才會讓硬件認為你是內(nèi)核態(tài)或者用戶態(tài),其實只設(shè)置 1 位就行了,那剩下那些位干嘛?這個地方就留了點余地,用來做一些事情的,其中一個事情是 PAC。
像剛才說的架構(gòu)三個最基本的是:匯編語言、異常和內(nèi)存管理。如果我知道了 ARM架構(gòu)下面只有一位去控制內(nèi)核空間還是用戶空間,當(dāng)我去看 PAC 的時,就能夠理解它為什么能用,一旦我有這個知識后,再去看白皮書會發(fā)現(xiàn)白皮書寫得好清楚,它其實就是按照基本的 3 個線索去寫的。包括我們?nèi)タ?PAC 時,關(guān)注 PAC 要用到哪些指令,如果你知道了 ARM架構(gòu),因為 ARM架構(gòu)是 RISC 的,它是 load/store 模型,我再去看 PAC 指令里面,我自然而然就會找出,因為 PAC 要去做指針認證,肯定是在跟 load/store 相關(guān)的地方,就很容易看到 PAC 到底是哪兩條匯編指令(PACIASP和AUTIASP)
但是這就有一個問題,本來持硬件支持一個 PAC 能力是為了支持我做一些更安全的事情,但是我又希望軟件通用。例如我們不能一邊支持 PAC,另一邊硬件如果不支持 PAC,我直接死給你看,這也不合適是吧?所以我們應(yīng)該做軟件方案的時候,同時考慮到硬件支持或不支持 PAC?這就涉及到一個代碼歸一的問題。那么最近內(nèi)核做了一個事情, shadow stack 里面的代碼有個歸一的動作,它不管你有沒有支持 PAC,都能讓系統(tǒng)跑起來。
我怎么去更好地在軟件的執(zhí)行流過程中,讓軟件的控制流不會被篡改?shadow stack 是其中的一個方法,它通過影子棧的方式去保證函數(shù)在調(diào)用過程中函數(shù)的返回地址是沒有被篡改。
3.2 Intel通過FineIBT支持細粒度的間接跳轉(zhuǎn)跟蹤(Indirectbranch Tracking)
一旦我們想到這一點,會自然地想說,既然 shadow stack 是其中的一個方法,會不會有其他方法?說到其他方法,確實是有其他方法。比如大家知道這函數(shù)調(diào)用過程中,其實大概就有點兩種非常典型:一種情況是固定的函數(shù)調(diào)用,比如說 A 函數(shù)調(diào)用 B 函數(shù)。還有一個情況是間接跳轉(zhuǎn),比如我在內(nèi)核里注冊一個 file_operations 結(jié)構(gòu)體,并填了一堆指針去調(diào)用,這種其實就是一個間接跳轉(zhuǎn)。
其實要去看寄存器是什么地址,跳到寄存器的地址,這種情況下本來就是動態(tài)可變的,運行時才知道跳轉(zhuǎn)的位置。但如果別人去篡改這個東西,相對來說也比較容易,因為你本來就是一個變量。我怎么去防止別人去借助間接跳轉(zhuǎn)去做一些攻擊呢?
在 6.2 內(nèi)核版本里面, Intel 就通過 FineIBT 方式去做細粒度的間接跳轉(zhuǎn)跟蹤。所以你看這些都是跟匯編語言相關(guān),再往抽象的地方看其實是跟控制流相關(guān)的東西。
3.3內(nèi)核增加了減緩Retbleedd補?。⊿pectre的變種)
它是 18 年的 Spectre 的一個變種, 它跟 Spectre 2 其實是很類似的。它其實也是跟跳轉(zhuǎn)相關(guān)的一個東西。所以如果我們想去看,Spectre 到底是怎么去修改的?其實我還是要去先了解,到底在跳轉(zhuǎn)過程中有哪些問題。比如其中的一個問題,如果每一次要跳轉(zhuǎn)時候,我才去做跳轉(zhuǎn)的動作,并且跳轉(zhuǎn)之后再去讀取我后面跳轉(zhuǎn)之后所需要的數(shù)據(jù),這樣很有很顯然會造成一個性能的開銷。
所以在所有 CPU 里面,它都會有一個叫 speculative(投機),在有跳轉(zhuǎn)的時候,先猜一下你會往哪邊調(diào),跳的要訪問的數(shù)據(jù)和指令先給讀回來,這個叫 speculative,這本來是個性能優(yōu)化。
但是這樣就有個問題,猜對了和沒猜對你的執(zhí)行時間不一樣,我就可以通過你的執(zhí)行時間去知道到底你猜沒猜對,也就是我可以通過你的執(zhí)行時間去知道到底你的變量。比如我一個 if (a == 1) 執(zhí)行什么, if (a != 1) 執(zhí)行什么,通常不同分支的執(zhí)行時間不同,這樣我就間接我知道你變量多少了。也就是非法獲得了原本沒有權(quán)限看到的數(shù)據(jù),這就變成一個攻擊。這就是 Spectre 背景, Retbleed 其實就是也是 Spectre 的一個變種,這次內(nèi)核針對x86的改動,是怎么去減緩這種攻擊。
3.4 Intel TDX guest的支持
TDX 其實是一個為了可信計算做的一個東西,簡單來說,我怎么在虛擬化的環(huán)境下面能夠比較容易做可信計算。
一旦我們說到虛擬化,很顯然它其實也涉及到虛擬機 guest 跟 host 是怎么去切換的?這個背后就是我們剛說的體系結(jié)構(gòu)三個基礎(chǔ)之一異常管理這個地方。你把這點搞清楚了,可能再去看這個特性就會比較清楚。比如 TDX 里面,它其實也有很核心的內(nèi)容,有一個叫 virtualization exception(#VE) ,它是怎么去做的,包括它跟內(nèi)存什么關(guān)系。其實你通過這個東西你就可以比較容易對 TDX 有一個了解。
3.5 Linux 6.2其他的更新
?龍芯的LoongArch架構(gòu)支持了ftrace,休眠/環(huán)境,休眠到硬盤,棧保護機制。
?CXL繼續(xù)改進對PMEM的支持。
?BPF的一些能力增強,例如可以操作task_struct,可以定義自己的數(shù)據(jù)類型;
?更多Rust支持的合入,離有實際功能的Rust驅(qū)動,越來越近了。
?共享匿名內(nèi)存可以命名了。之前只有私有匿名內(nèi)存才可以命名。
?squashfs(一個壓縮的只讀文件系統(tǒng))可以通過threads選項,在運行時配置使用幾個CPU做并行解壓縮;支持了在文件系統(tǒng)掛載時的用戶ID和組ID的映射。
?阿里的張?zhí)旒烟峤涣薴scrypt中CM4加密的支持。SM4在2016年成為國密算法。
?內(nèi)核可以編譯時不再支持NFSv2,后續(xù)會刪除這個特性。NFS最新的版本是NFSv4。
?perf增加tasks-analyzer,可以分析進程運行時間或被調(diào)度走的時間。
?內(nèi)核增加了單獨的加速器驅(qū)動accel。Intel ivpu將是第一個使用這個框架的設(shè)備。
?裕太微的YT8521網(wǎng)絡(luò)Phy芯片的驅(qū)動,而且用的是裕太微的郵箱,和只前面是社區(qū)的朋友貢獻相比,裕太微的郵箱往往也意味著公司對社區(qū)的更加重視。
?瑞芯微和全志都有對IOMMU的fix。
審核編輯 :李倩
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1415瀏覽量
41252 -
Linux
+關(guān)注
關(guān)注
87文章
11496瀏覽量
213247 -
代碼
+關(guān)注
關(guān)注
30文章
4894瀏覽量
70448
原文標題:張?。篖inux內(nèi)核的最新進展(6.2版本)
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
評論