RFC-0201:收回訪客 VM 記憶體

RFC-0201:回收訪客 VM 記憶體
狀態已接受
區域
  • 虛擬化
說明

允許主機使用先前已配置及後來釋出的訪客 VM 記憶體

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2022-12-15
審查日期 (年-月-日)2022-12-01

摘要

允許主機回收訪客使用的記憶體。

提振精神

在訪客模式中執行記憶體需求高的應用程式,以及在主機模式中啟動記憶體需求高的應用程式,可能會導致 OOM,即使訪客模式記憶體不再使用也一樣。

原因有兩個。

  1. 我們目前不允許主機自動從訪客取得記憶體。
  2. 我們不支援讓訪客主動告知房東「這是未使用的記憶體頁面清單,如有需要,歡迎使用」的方式。

使用者歷程範例

  1. 啟動 termina 或 debian 訪客
  2. 在訪客模式中啟動記憶體需求高的應用程式
  3. 在訪客模式中關閉記憶體需求高的應用程式
  4. 在主機上啟動記憶體需求高的應用程式
  5. 觀察主機是否發生 OOM 問題 💥

背景

作業系統啟動時,會詢問硬體 (在虛擬機的情況下為虛擬機管理程序) 有多少實體記憶體。如果主機告知虛擬機有 4 GiB 的 RAM,虛擬機就會知道它可以配置約 100 萬個 4 KiB 的頁面。

方法是引入一個層級,將系統認為是實體位址的內容 (稱為「Guest Physical Address」) 與實際實體位址 (稱為「Host Physical Address」) 對應。提醒您,第一層位址轉譯是將訪客虛擬記憶體位址與訪客實體位址進行對應。換句話說,硬體會先將來賓虛擬位址轉譯為來賓實體位址,然後再轉譯為主機實體位址。硬體會使用由來賓作業系統管理的頁面表進行轉譯,而後者則由管理程序管理的頁面表控制。

訪客會處理其自身的頁面錯誤,這些錯誤是在存取未對應的訪客虛擬到訪客實體位址時發生。虛擬機器人會處理從實體來賓到實體主機的轉譯作業的頁面錯誤。

我們使用分頁記憶體,也就是說,當輔助執行管理員將 X GiB 的 RAM 提供給來賓時,不會預先分配任何記憶體,而是在實際需要這些頁面時才分配。在這種情況下,表示訪客嘗試存取頁面。從管理程序的角度來看,已分配的實體記憶體頁面屬於對應的虛擬機器,無法用於主機程序。

因此,在主機記憶體不足以執行自身程序時,執行個體可能會擁有大量未使用的已配置實體記憶體頁面。

以下將介紹 2 種讓主機存取訪客記憶體的方法:

Virtio-balloon

主機可以透過設定目標氣球大小,告知訪客 virtio-balloon 驅動程式庫將氣球調整為特定大小。inflate充氣氣球表示輔助作業系統會保留所需的記憶體頁面數量,並將已分配記憶體頁面的輔助作業系統實體位址回報給主機。從這個時間點開始,主機可以取消提交已回報的記憶體頁面,並使用已回報記憶體的實體記憶體。

如果 virtio-balloon 協商 VIRTIO_BALLOON_F_DEFLATE_ON_OOM,Guest 隨時可以再次開始使用記憶體。請參閱 Virtio 規格 5.5.6.1。我們目前已啟用 VIRTIO_BALLOON_F_DEFLATE_ON_OOM。

主辦人可以減少氣球的目標大小,讓訪客重複使用氣球中的頁面。如果設定的氣球大小小於氣球中的實際頁面數,訪客可能會重複使用先前提供給氣球的頁面。如果訪客想再次使用記憶體,系統會 deflate 氣球,讓房東知道訪客日後會使用一系列實體訪客位址。在壓縮後,當已從熱氣球中移除的來賓存取頁面,會發生從來賓物理主機物理頁面錯誤,而虛擬機器會為來賓分配新的物理記憶體頁面。

如需 virtio-balloon 核心功能的詳細說明,請參閱 Virtio Balloon. 幻燈片Virtio Balloon. 影片

免費網頁報表

2020 年,virtio-ballon 推出了「免費網頁報表」新功能。

免費頁面回報功能可讓房客將免費記憶體頁面回報給房東。方法是將 4 MiB 大小 (Linux 實作常數) 的可用頁面加入可用頁面報表,並將報表傳送給主機。房客保證不會重複使用任何免費頁面,直到房東確認報表為止。

主機收到可用頁面報表時,會解除記憶體頁面,讓主機應用程式使用這些頁面,並將回報傳回給客體。此時,訪客可以重複使用先前已解除鎖定並確認的頁面。如果訪客決定重複使用該頁面,主機會偵測到訪客實體與主機實體頁面錯誤,並分配新的實體頁面來滿足訪客要求。

詳情請參閱 Free page reporting: by Alexander Duyck ( Intel ). Slide 10

相關人員

協助人員:

  • cpu@google.com

審查者:

  • abdulla@google.com
  • dahastin@google.com
  • tjdetwiler@google.com

諮詢:

  • cwd@google.com

社會化:

這份 RFC 已接受虛擬化團隊的審查。我們已與 cwd@google.com 討論解決方法,該團隊正在解決 ChromeOS 的類似問題 (但規模較大)。

設計

目標

  • 在訪客端執行應用程式後,為主機回收記憶體。
  • 盡量減少記憶體回收對宿主和訪客的效能影響。

Non-Goal

  • 在多個訪客之間平衡大量記憶體用量。
  • 在訪客和主機競爭記憶體時,動態設定應用程式的優先順序。
  • 支援 Fuchsia 訪客的記憶體回收功能。

成功標準

  • 在「動機」一節所述的使用者歷程中,Fuchsia 不會發生 OOM。
  • 主機的可用記憶體會大致恢復到在子機器人中執行記憶體密集應用程式之前的狀態。
  • 在記憶體回收前後,Guest 可繼續執行記憶體需求高的應用程式。
  • 除非主機的記憶體壓力偏低,否則訪客頁面快取不會受到影響。
  • 至少有一個客體執行時,主機 OOM 的數量大幅減少。

愜意

  • 使用 virtio_balloon 中的空白頁面回報功能,為主機使用者釋出空閒記憶體。
  • 在「低」和「嚴重」主機記憶體壓力事件上充氣氣球,以清除來賓網頁快取並回收分散的記憶體頁面。
  • 概念驗證證實,免費頁面回報確實會如預期回收記憶體。

實作

使用免費的網頁報表

我們會使用Free page reporting 功能,向主機回報並回收所有可用記憶體。

All 是指 PAGE_REPORTING_MIN_ORDER 以上的任何順序 (在 Linux 核心中定義為 4 MiB)。

使用空白頁報表後,系統會在接下來 30 秒內回收大部分的記憶體。回報的可用頁面大小為 2 MiB 或 4 MiB,因此預期會有一定程度的記憶體碎裂。在訪客端,免費頁面報表會分批發布,以盡量減少對效能造成的影響。

Linux-5.15 會在 30 秒內以 2 MiB 和 4 MiB 的區塊,回報大部分的可用記憶體。

空白頁面回報功能不會移除 Linux 頁面快取,如果執行的是 I/O 密集工作負載的來賓,這可能會造成問題。如要瞭解 Linux 中的頁面快取,請參閱「Linux 頁面快取基礎知識」。

日後 Linux 訪客映像檔開始使用 MGLRU 時,這個情況可能會有所改變。請參閱 MGLRU 的「缺點、替代方案和未知事項」一節。

不隨意刪除網頁快取是好事,因為快取存在是有原因的。主機應只在實際需要時,從訪客頁面快取中取用記憶體。也就是說,我們需要提供一種方法,在主機記憶體不足時,回收用於頁面快取的訪客記憶體。

在主機記憶體壓力下充氣訪客氣球

第二項變更是使用記憶體壓力提供者,在主機記憶體警告和嚴重警告層級顯示氣球。

充氣可達成兩個目標:

  • 將訪客頁面快取淘汰,這項操作對於訪客執行密集檔案 I/O 並填滿頁面快取時非常重要。
  • 回收大部分的零碎記憶體頁面,因為氣球擴充是在 4KiB 精細度下完成,而免費頁面回報則使用 4MiB。

膨脹量會與可用的訪客記憶體成正比。在主機記憶體事件發生警告和重大警告時,氣球會膨脹至可用外部記憶體的 90%。我們必須在 WARNING 和 CRITICAL 事件上進行擴充,以防空閒記憶體從 NORMAL 急遽降至 CRITICAL。主機記憶體壓力恢復正常時,氣球會縮小至 0%。

我們希望避免在主機記憶體不足時,不斷地充氣和洩氣。氣球充氣會對房客和房東造成效能成本。此外,根據 Intel 的說法,持續的氣球大小調整會導致許多 TLB 關閉

為避免氣球大小來回擺動,我們會將氣球充氣作業調節為每 X 秒充氣 1 次。在 teamfood 測試期間設定的 X。初始值為 1 分鐘。可能會有更多逾時情形,例如如果主機處於記憶體壓力警告狀態太久,就會出現用於摺疊氣球的逾時情形。您可以根據 Teamfood 測試遙測資料新增其他逾時時間。

成效

當使用者在訪客中執行記憶體需求高的應用程式時,實作記憶體回收功能可改善主機記憶體效能。主機將有更多記憶體可供使用,而非在來賓有可回收的記憶體時,改用記憶體壓縮和其他 CPU 耗用大量資源的方式來取得記憶體。

在 Linux 實作中,空白頁報表作業會以 30 秒的間隔進行,以減少對訪客的效能影響。我們預期在記憶體密集型來賓工作負載中,效能會受到 1%-2% 的影響。請參閱「免費網頁報表基準值」。

在主機記憶體不足時展開 Balloon,可能會為主機和 Guest 增加額外負載。

我們需要評估主機在記憶體壓力下運作時,是否啟用記憶體回收功能,以及「TLB 終止」中斷的次數。

基準:

要擷取的指標

  • 基準測試回報的一般指標,用於偵測效能退步
  • 基準測試前後,在執行個體和主機的可用記憶體
  • 在訪客中執行 TLB 終止中斷

安全性考量

回收的空閒頁面會在解除提交作業中歸零,這與氣球充氣相同。這樣可避免房客資訊洩漏給房東和其他房客。

測試

大部分的工作都會由單元測試和 2 項整合測試完成。其中一個整合測試會涵蓋免費頁面回報記憶體回收作業,另一個則會涵蓋訪客頁面快取和氣球展開作業的互動情形。

我們會手動測試動機部分所述的使用者歷程。使用者歷程仰賴訪客啟動,因此不具密封性。如果我們有自動化端對端虛擬化測試,則可擴充至涵蓋這類情況。我們認為,為這項 RFC 建立自動化端對端虛擬化測試的做法並不實際。

缺點、替代方案和未知事項

多代 LRU 架構

多世代 LRU 架構 (又稱為 MGLRU) 是 Linux 核心的記憶體改善功能。Linux 目前的頁面回收機制在 CPU 使用量方面成本過高,而且經常會做出不當的選擇。MGLRU 的目標是提供比目前 Linux 核心頁面回收程式碼更佳的選擇,並以更有效率的方式執行。Google 工程師的數據顯示,冷啟動時間最多可縮短 16%,同時減少低記憶體終止的情況,ChromeOS 的記憶體不足終止情況減少 59%,瀏覽器中低記憶體分頁丟棄情況減少 96%,而伺服器的結果也十分樂觀。

詳情請參閱 PATCH v14 00/14 Multi-Gen LRU Framework

我們目前使用的 Termina 5.15 沒有 MGLRU 修補程式。上游不支援 MGLRU。Termina 核心開發人員正在等待 MGLRU 獲得上游接受,以便回移至 Termina 5.15

MGLRU API 可用於驅動免費網頁報表邏輯。建議您使用 MGLRU API,以改善 Linux 核心中的空白頁面回報效能。如果成功,可以提議將其合併至上游。這項功能會對 Linux 核心中現有的免費網頁回報解決方案進行最佳化。

允許主機回收訪客記憶體時,不會依附 MGLRU。

固定氣球大小的替代做法

原本建議的記憶體回收方式,因此稱為記憶體守護程序。

這是 ChromeOS 目前採用的方法。但也有許多缺點

  • 需要選擇輪詢時間間隔。
  • Intel 已回報,即使是小型氣球調整,也會造成效能負擔。請參閱「持續調整氣球大小會導致許多 TLB 關閉
  • 為了讓這個功能正常運作,您必須隨時將氣球充氣至大約 90% 的訪客記憶體。
  • 客體應用程式可快速配置,並在下一個輪詢間隔前遭到 OOM 守護程序終止

ChromeOS 方法

ChromeOS 目前正在開發下一個版本的 Responsive virtio-balloon。簡而言之,這個想法是在主機和客體中使用記憶體不足終止工具,調整氣球大小,而非終止應用程式。我們也打算使用 MGLRU 來引導氣球大小調整邏輯。

ChromeOS 解決的是更困難且不同的問題:

  • ChromeOS 有許多訪客和主機,這些元件都會爭奪記憶體
  • ChromeOS 和所有訪客都會連結 MGLRU 和記憶體不足終止工具 Daemon。
  • 選擇正確的氣球大小,是所有工作負載都難以解決的問題。
    • 我們必須定義一組經驗法則,以引導氣球的充氣/洩氣邏輯
    • 因此,您必須取得機群裝置的資料,才能建立推論法並分析其效能。
    • 更重要的是,如果您使用 LMKD 觸發氣球的充氣/洩氣,則必須快速調整氣球大小,否則 OOM 殺手會在氣球充氣/洩氣時終止應用程式

Fuchsia 虛擬化沒有大量裝置艦隊可用於收集統計資料。我們要解決的問題簡單得多。Fuchsia 沒有可連結的 OOM 殺手。

Fuchsia 主機可同時執行多個客體 (Termina、Debian、Fuchsia)。目前這不是主要用途,使用者和測試通常會執行單一訪客。一旦開始使用效能更強大的硬體,這項規定可能會有所變動。如果使用者未使用所有可用記憶體,建議的解決方案可用於多位超額訂閱的使用者。例如閒置的 Debian 訪客和處於活動狀態的 Termina 訪客。

如果我們必須支援多個嘗試使用所有可用記憶體的訪客,問題空間就會變得更大。決定哪個訪客應用程式或哪位訪客較為重要,應由產品政策決定。我們應專注於為產品提供適當的工具,但在平台層級,我們不希望對如何處理低記憶體做出規定。

我們會採用更簡單、更容易預測的解決方案來解決目前的問題,同時新增資料收集功能來分析 OOM,並瞭解是否需要加入更複雜的推論法。

使用 DAX 和 virtio-fs 共用主機和來賓頁面快取

DAX 對應可讓訪客直接存取主機快取中的檔案內容,因此可避免訪客和主機之間的資料重複。使用 DAX 新增 virtio-fs 支援、啟用網頁快取共用功能,以及在記憶體壓力下新增網頁快取棄用功能,是清除訪客網頁快取的 virtio 氣球擴充功能替代方案。由於氣球展開,因此精細的網頁快取控制項會比全面的網頁快取淘汰功能更為理想。我們可以捨棄舊的頁面快取,同時保留新的快取,藉此減輕記憶體壓力,且不會過度影響主機/訪客效能。

既有技術與參考資料