LWN: folio 改動未能合入!
關(guān)注了就能看到更多這么棒的文章哦~
The folio pull-request pushback
By Jonathan Corbet
September 10, 2021
DeepL assisted translation
https://lwn.net/Articles/868598/
在我們上次介紹 page folio 的時候,當時看來它有望在 5.15 合并窗口期間被合入 mainline。Matthew Wilcox 在 8 月份正式發(fā)出了一個 pull request,希望能合入 mainline。雖然 folio 仍有可能被合入到 5.15 版本,但截至目前還沒有達成這個目標,并且可能性越來越小了。我們只看到關(guān)于 folio 方案價值的長長的討論。
內(nèi)核中內(nèi)存管理子系統(tǒng)是以 page 為單位來管理內(nèi)存的,這個基本單位通常由硬件決定(一般是 4KB 大?。?。不過這些 "base" page 非常小,內(nèi)核經(jīng)常需要以更大的單位來處理內(nèi)存。為此,它將一些在物理上連續(xù)的 page 組合成 compound page,它們都是由一個 head page(指 compound page 復(fù)合頁中的第一個 base page)和一些 tail page 組成的。這就導(dǎo)致了這樣一種情況:內(nèi)核代碼收到一個 struct page 的指針時,如果不仔細檢查一下的話,就無法知道它在處理的是 head page 還是 tail page。
事實證明,在代碼中加上 "確保這是一個 head page" 的檢查在內(nèi)核運行時增加了一些開銷。并且內(nèi)核中到處都在使用 struct page,也使得內(nèi)核的 API 變的有些不明確,因為很難知道某個函數(shù)是否能夠處理 tail page。為了解決這個問題,Wilcox 創(chuàng)造了 "folio" 的概念,它就跟一個 struct page 很像,但可以確定的是它絕對不會是一個 tail page。通過改變 kernel 內(nèi)部的函數(shù)來使用 folio 結(jié)構(gòu),Wilcox 提升了內(nèi)核的運行速度,并且同時讓 API 更加清晰了。這個 patch set 是非常巨大的,到處都在進行修改(intrusive),但之前似乎已經(jīng)克服了大多數(shù)阻礙,做好進入 mainline kernel 的準備了。
Objections
內(nèi)存管理開發(fā)人員 Johannes Weiner 很快地回復(fù)了這個 pull request,他對 folio 這個概念表示 "strong reservations"。在后續(xù)討論中,他把自己的反對意見用多種方式講述了出來,但似乎都歸結(jié)為一個核心問題:folio 只是一個物理上連續(xù) page 的集合,這將使它難以處理內(nèi)存管理所面臨的一些挑戰(zhàn)。
首先,folio 的設(shè)計泄露了太多內(nèi)存管理方面的內(nèi)部信息給其他那些使用了 folio 結(jié)構(gòu)的子系統(tǒng),尤其是在文件系統(tǒng)子系統(tǒng)中更是如此。當然,目前使用 page 結(jié)構(gòu)的 API 也有同樣的問題,但他說,大規(guī)模的 API 變動正好是解決這個問題的時機。因此,Weiner 多次要求創(chuàng)建一個更抽象的內(nèi)存描述方式,用來供內(nèi)核的更高層次的模塊使用。這種抽象可以隱藏很多細節(jié),并且 folio 現(xiàn)有的物理連續(xù)、2次方 size 內(nèi)存塊的這些假設(shè)條件也可以被消除了。
他繼續(xù)說道,物理連續(xù)的這個前提條件是一個嚴重問題,因為內(nèi)存管理子系統(tǒng)從來都不擅長分配較大的、連續(xù)的內(nèi)存塊。在某些場景中,系統(tǒng)中大多數(shù)內(nèi)存都碎片化了,找不到更大的連續(xù)內(nèi)存塊了。像 page compaction 這類技術(shù)可以在一定程度上有所幫助,但它的代碼就是帶來更高的分配延遲。他說:“事實上我們在這方面已經(jīng)宣告失敗了?!痹诓唤鉀Q分配這些大塊連續(xù)區(qū)域的情況下,光采用 folio 來表示更大的內(nèi)存連續(xù)區(qū)域就是沒有意義的。
他說的另一個問題是 folio 的概念可能會使今后改動內(nèi)存管理子系統(tǒng)來使用更大的 base page size 變得更加困難。這種改動會使系統(tǒng)在許多方面更加有效率,比如減少浪費在 struct page 上的內(nèi)存,以及減少用于處理這些結(jié)構(gòu)的 CPU 時間。但是,有一個問題導(dǎo)致內(nèi)核多年來一直沒有增加 base-page size:internal fragmentation(內(nèi)部碎片化)。
當一個文件的內(nèi)容(或其一部分)被存儲在 page cache 中時,就需要一定數(shù)量的完整 page。類似 Unix 這樣的系統(tǒng)有很多小文件,但即使是一個幾個字符的文件也會在 page cache 中占據(jù)一個完整的 page。該 page 中文件末尾的內(nèi)存全都被直接浪費了。增加 base page 的大小必然也會導(dǎo)致因這種內(nèi)部碎片而損失的內(nèi)存數(shù)量變得更多。在以前的一個討論中,Al Viro 做了一個快速計算,說明在更大的 page size 下要保持內(nèi)核源代碼都在內(nèi)存里的話需要多少內(nèi)存。例如,64KB 的大小將使要用到的內(nèi)存 size 翻兩番。這個代價不算小了。
出于這個原因,Weiner 認為,即使內(nèi)存管理子系統(tǒng)后續(xù)轉(zhuǎn)向更大的 base-page size,內(nèi)核也需要能夠以小的單位(例如現(xiàn)有的 4KB 大?。﹣磉M行 file caching。換句話說,page cache 需要能夠使用內(nèi)存中比 page 更小的單位來進行工作。因此這里如果能使用新的內(nèi)存抽象的話可能會促進這一點。而目前的 folio 概念則由于與底層 page 牢牢地聯(lián)系在一起,因此無法有所幫助。
Wilcox 對這個反對意見的回答似乎是說,使用不同于 allocation size 的單位來管理內(nèi)存的話并沒有什么好處。因此,在內(nèi)存管理子系統(tǒng)中使用較大單位頁面的方法就是分配 compound page,并用 folio 來代表之。如果內(nèi)核中的所有內(nèi)容都使用較大的 page,內(nèi)存碎片就會減少,這些 page 也就會更容易分配出來。對于需要較小 page size 的場景,例如小文件的 page-cache entry 項,就可以直接使用 base page。通過仔細進行分配,就可以讓這些單獨的 page 可以 pack 起來,進一步避免了碎片化。
但是,Weiner 不同意這種方法,他認為這把避免碎片的責任歸結(jié)給了錯誤的地方。內(nèi)核的內(nèi)存分配有兩個層次:page allocator(這里處理單位是完整 page,也就是 folio 相關(guān)的地方)和 slab allocator(通常用來處理較小單位的內(nèi)存分配)。它們優(yōu)勢不同:
page allocator 擅長分配統(tǒng)一的(uniform)、較大的內(nèi)存區(qū)域。slab allocator 擅長將這些區(qū)域細分為更小的對象,做好整齊的 pack 和 group 管理工作來方便后續(xù)回收成連續(xù)內(nèi)存,同時向用戶空間和內(nèi)核空間的開發(fā)者提供了每種內(nèi)存使用情況以及內(nèi)部碎片的詳細劃分。
據(jù) Weiner 說,Wilcox 的方法讓 page allocator 來處理目前在 slab allocator 中已經(jīng)很好地解決了的問題。"如果這就是你希望 folio 后續(xù)做的事情,那么很抱歉,我只能回復(fù) NAK"。
The real problem with folios
當然,是否合并 folio,最終決定是由 Linus Torvalds 決定的。在討論的早期,他對 API 的改進給予了肯定,但也指出,這組 patch set 確實給內(nèi)存管理子系統(tǒng)帶來了大量干擾。他總結(jié)說 "所以我并不討厭這些 patch。我認為它們很聰明,很可能是值得的,但我也肯定是不喜歡它們的。"
然而,他也指出,他對 "folio" 這個名字并不是很滿意,這就又來到了內(nèi)核社區(qū)討論中一個經(jīng)常出現(xiàn)的規(guī)律:當技術(shù)問題討論很深入并難以解決的時候,一定會開始對 name 進行擴展辯論了。所以 David Howells 建議用 "sheaf" 或 "ream"。Torvalds 則傾向于更直接的描述性的東西,比如 "head_page"。Ted Ts'o 認為 "mempages" 也可以,或者是 "pageset"。Nicholas Piggin 贊成 "cluster" 或 "superpage"。在討論之后,Vlastimil Babka 總結(jié)下來唯一合適的名字是 "pageshed"。
Wilcox 已經(jīng)說得很清楚了,他并不關(guān)心這個名字是什么,只要能把代碼合入進去,他幾乎可以接受任何名字。他重做了 pull request,把所有地方都重命名為 "pageset",就證明了這一點。不出意料,這個分支討論并沒有得出什么真正的結(jié)論。
8 月底的時候,Howells 發(fā)文請求盡快解決這個問題,因為還有很多其他有待解決的內(nèi)存管理工作,它們要么依賴于 folio patch,要么與之沖突。他問道:
是否有可能按原樣直接接受 folios patch set 并接受這個名字,或者只接受 Willy 的重命名之后的版本(盡管它還沒有經(jīng)過 linux-next 的驗證)?還是說這個方法有著根本性的缺陷,需要重做?
David Hildenbrand 補充說,他希望看到 folios 能以任何方式從 linux-next 中移出去,越早越好。
Now what?
現(xiàn)在看來對話已經(jīng)結(jié)束了。5.15 合并窗口已經(jīng)接近尾聲,而 Folio patch 還沒有被合入。這意味著,folio patch set 最起碼也得再等待一個開發(fā)周期了。Torvalds 有時候會將有爭議的 patch 保留到(甚至超過)合并窗口的結(jié)束時間點,那時會有更多的時間來考慮。因此,即使是合并窗口關(guān)閉了,也不意味著他已經(jīng)作出了決定。
最后結(jié)果還沒有出現(xiàn),但無論如何很明顯的是,在內(nèi)存管理子系統(tǒng)中還有很多工作要做。很多需要進行的改動還沒有被設(shè)計出來,更不用說編寫代碼和調(diào)試了。這為 Wilcox 的最后一個論點增加了一些支持。"Folio patch 現(xiàn)在已經(jīng)是個現(xiàn)成版本了"?;蛘撸?Babka 問到的:"我們是否應(yīng)該什么都不做,一直到有人真正把這個假設(shè)中的未來變成真實代碼,然后我們再看它是否有效?" 如果 folio 的代碼被拋棄了,那么基于它進行的對內(nèi)存管理內(nèi)部進行的改進工作將不得不從頭開始,而目前還看不出有什么人準備好了要接受這一挑戰(zhàn)。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~
