RFC-0209:記憶體優先順序設定檔

RFC-0209:記憶體優先順序設定檔
狀態已接受
區域
  • 核心
說明

使用設定檔將 VMAR 標示為優先順序。

問題
  • 101641
變更
作者
審查人員
提交日期 (年/月)2022-08-16
審查日期 (年/月)2023-02-15

摘要

使用設定檔物件指示核心,允許將設定檔套用至 VMAR,藉此將網頁錯誤及其他會增加記憶體存取延遲時間降到最低的作業。

提振精神

Zircon 是過度修訂系統,採用了不同的回收系統來嘗試支援這些應用程式。這些撤銷方法包括撤銷、頁面表格重構、零頁面掃描等,但可能會在期限任務中產生期限,因為他們會增加記憶體存取作業的不可接受的延遲時間。此外,網頁壓縮等未來的潛在重新拆解方法也會有問題。

音訊是重複的例子,核心的所有重組作業導致音訊執行緒中後續的頁面錯誤,都可能導致音訊執行緒錯過期限。

到目前為止,解決方法是核心中的特殊案例解決方法,目的是停用所有類型的重新裝飾,僅針對音訊相關元件。然而,這個做法相當脆弱,無法擴充給有類似需求的其他使用者。

此 RFC 旨在提供適用於音訊的一般機制,取代現有的暫時性解決方法,以及其他任何元件。

相關人員

講師:

jamesr@google.com

審查者:

eieio@google.com, rashaeqbal@google.com、tombergan@google.com

顧問:

andresoportus@google.com

社群媒體化:

此問題和提案有關 Zircon 團隊和核心 Evolution Working Group (KEWG) 的文件中討論。

API 設計

為提供使用者重組的控制項,我們將以下列兩種方式擴充設定檔物件:

  1. 系統會新增 zx_profile_create 的額外旗標 ZX_PROFILE_INFO_FLAG_MEMORY_PRIORITYmemory_priority 欄位。
  2. 這樣就能透過 zx_object_set_profile 將設定檔套用至 VMAR。

一開始只支援兩個 memory_priority 欄位值:ZX_PRIORITY_DEFAULTZX_PRIORITY_HIGH,這種動作會永久停用所有重組功能。日後 Room 也將支援更多級別,讓您能在盡可能縮短延遲時間及避免 OOM 之間取捨。

將設定檔套用至 VMAR 時,假設該設定檔具備有效的 memory_priority,就會立即套用至該 VMAR 及其所有子區域,並覆寫任何先前套用的設定檔。

核心要求核心會遵循 ZX_PRIORITY_HIGH 設定,且核心「必須」停用標示 VMAR 中的任何動態回收功能。

ZX_PRIORITY_DEFAULT 設定沒有特定意義,也不必遵循。具體來說,我們允許核心 (主要是為了方便實作) 將 ZX_PRIORITY_HIGH 要求擴充至標示為 ZX_PRIORITY_DEFAULT 的更廣範圍。

雖然系統一律允許使用應用程式,但如果位址空間因某些 ZX_PRIORITY_HIGH VMAR 而不存在,則核心「應」返回未套用任何設定檔時的相同狀態。

資訊查詢

zx_object_get_infoZX_INFO_KMEM_STATS_EXTENDED 主題會延伸,以回報額外欄位:

    // The amount of memory in VMOs that would otherwise be tracked for
    // reclamation, but has had reclamation disabled.
    uint64_t vmo_reclaim_disabled_bytes;

元件使用方式

使用者空間元件通常不會直接使用 zx_profile_create 等元件,也不會叫用 ProfileProvider 服務。此處的 ProfileProvider SetProfileByRole 方法會放寬為接受任意控制,而非只有執行緒。

核心設計

本節說明如何變更核心中的物件,以便容納設定檔中的資訊。目標是確保在做出決策時需要知道記憶體優先順序的任何系統部分,有利於有效率地存取。在這個設計中,這項設計會盡可能以在設定檔應用程式的點執行作業,假設設定檔應用程式會比其他作業低頻率。

減少布林值

與重組有關的核心物件如下:

  • VmAspace - 此處為控制項頁面表格對應關係和頁面表格重新調整功能。
  • VmAddressRegion - 目前未涉及重組作業,但建立所有頁面表格對應關係時,都會透過這個物件完成。
  • VmObject - 如果遭到除名或日後的頁面修復策略,則需透過 VmObject

除了 VmAddressRegion (已套用設定檔的物件) 之外,每個物件都能針對其任何子範圍查詢、該範圍內存在的 VMAR,以及套用的記憶體優先順序。

同時擁有多個優先順序不同的 VMAR,並能透過套用最高優先順序解決 VMO 區域的問題。

為避免在所有 VMAR 中重複執行長時間搜尋,物件需要有效率的方式,才能判斷是否適用任何記憶體優先順序。為方便追蹤,初始提議的實作會將任何優先順序範圍升級為完整物件。也就是說,如果設定檔參照 VmObject 的任何部分,系統會將整個物件視為擁有該設定檔。

這兩種實作方式可以簡化記憶體分析查詢作業,只需透過物件連結傳播布林值聯集即可。

傳播

這個重組功能停用布林值會以邊緣轉換和計數為基準。

如果 VMAR 已設定設定檔,則需要考量三種結果:

  1. 這個 VMAR 的重建作業維持不變。
  2. 重新啟用功能會從已停用轉場效果。
  3. 復原功能會從已啟用轉變成已停用。

在第一個情況下,不會直接傳播,但所有子區域仍必須週遊,並將設定檔套用至這些子區域。您需要進行這種無條件週遊,因為子區域已套用不同的設定檔,因此需要覆寫。

在這兩種轉場效果中,VmAspaceVmObject 都需要更新。

相較於單一布林值,VmAspaceVmObject 物件在參照這些物件數量的物件計數器將會停用復原功能。因此,如要判斷這些物件是否停用重建功能,便是將計數與 0 進行比較的因素。

VmObject 可能有額外的 VmObject 父項,需要傳播標記。由於重組會控制計數器,或者不是零,因此當計數器轉換到零時,就會發生傳播情形。

這個參考計數傳播策略可以盡可能提高設定檔變更的效率,比起只追蹤布林值,幾乎沒有負擔。

VmObject 轉換

除了傳播重新宣告標記外,VmObject 也必須在轉換期間執行動作,以更新其頁面。

停用功能之後,凡是可以收回的頁面都會移到單獨的頁面佇列中。列入這個佇列不僅可防止網址遭到撤銷,也能提供計算頁面的方法。

同樣地,啟用重新宣告功能時,您也必須將頁面移回預設佇列,才能再次使頁面重塑候選項目。實作會詳細說明網頁重新放回預設佇列時要考慮的網頁存在時間。在沒有硬體存取標記的平台上,您將無法取得任何年齡資訊,因而必須發明年齡。

實作

實作將透過連續層的 API 完成核心實作的一系列步驟。

核心實作

提議對核心物件的變更設計可以全面實作,支援在不變更任何行為的情況下設定記憶體優先順序。這麼做會針對多個 CL 執行這項作業,並在核心單元測試中進行測試。

核心 API 變更

ZX_INFO_KMEM_STATS_EXTENDED 查詢需要具有相當特殊權限的系統資源,而且全都在樹狀結構中。因此,這項查詢可以在單一 CL 中修改,而無需多階段結構演變。

更新設定檔 API 和說明文件,並將設定檔系統呼叫連結至先前實作的核心支援。zx_profile_create 系統呼叫及其相關聯的設定結構 zx_profile_info_t 屬於特殊權限系統呼叫,因此也能在單一 CL 中修改。

ProfileProvider 變更

擴充 ProfileProvider 的實作,以支援在 .profiles 中指定記憶體優先順序的方式。

變更 ProfileProvider FIDL API,使其採用任意控點,而非只有執行緒。由於這是為了放寬 API 的條件,並不會破壞任何回溯相容性。

媒體遷移

媒體相關元件的相關設定檔將變更為包含 ZX_PRIORITY_HIGHmemory_priority,而所有媒體元件接著都會將這些設定檔套用至其根 VMAR 的方式,與套用至其執行緒的方式完全相同。

只要確認設定檔運作正常,即可移除現有硬式編碼核心解決方法。

效能

您提出的核心設計與核心中使用的臨時解決方法非常接近,但目前的臨時方法無法取消套用,且可永久套用至所有參與的 VMAR 和 VMO。因此,從這個方法切換至設定檔時,應該就功能和核心行為 (包括 CPU 和記憶體用量) 而言是完整的免人工管理。

安全性考量

使用設定檔及設定記憶體優先順序的能力,受到需要根工作控制的管制。因此,任何與阻斷服務攻擊相關的安全性考量因素,與 ProfileProvider 現有的阻斷服務攻擊情況相等。

測試

大部分的測試都可以著重於個別核心和設定檔提供者實作的單元測試,並會進行一些整合測試以驗證完整的使用路徑。

說明文件

將會更新設定檔物件、相關 syscall 和 FIDL 通訊協定的說明文件。

替代選項

VMAR 的特性或同等項目

您可以使用 VMAR 物件來指出其優先順序,而不必使用設定檔物件,而是直接在 VMAR 物件上設定屬性或對等項目。這可以避免將排程器物件的擴充功能擴充,並簡化使用者空間的使用情形,而且不需要使用 ProfileProvider

這種方法無法絕對可以限制設定優先順序的功能。雖然任何元件已可以分配任意記憶體並執行阻斷服務,但這未必是理想情況,而停用撤銷可能會視為提高效能的方法,也可能因此對常見情境造成嚴重的悲劇。

某些形式的客製化存取權控管設計可用於解決這個問題,但現在已經移除使用設定檔的好處。

透過 taint 推論

如果不想根據使用者空間直接標示任何內容,可以假設所有期限執行緒都需要期限記憶體存取權,並將存取的任何記憶體標示為高優先順序。這種做法不需變更使用者空間,但需要進行標記,每個位址空間至少具有一個期限執行緒具有所有對應標示;或者,只要使用者在期限執行緒使用完畢,系統就會標示對應 / VMO。

過度標示並非壞事,因為並非所有期限執行緒都有相同的記憶體延遲時間要求,而且並非所有位址空間都有相同的要求。延遲保留代表無法預做錯誤,因此在最糟的情況下,最糟的情況會讓期限執行緒總是錯過一次錯誤期限。

我們使用延遲標記的配置,也無法清楚標示出項目如何取消標示。

將 Memory_Priority 套用至執行緒

您不必將設定檔套用至 VMAR,只要在將設定檔套用至執行緒時,就可以解讀 memory_priority 欄位,並將優先順序套用至其根 VMAR。

雖然這簡化了 ProfileProvider 通訊協定和系統呼叫介面,但會使使用者和核心日後無法發揮更高的效率。有效率的元件可以整理在其位址空間的一個子區域中處理重要的延遲時間機密資料,並在另一個區域將非關鍵資料套用至重要區域。如此一來,非關鍵資料就能在重新編譯時考慮這類要求,進而有利於記憶體用量。

單一優先順序欄位

也可以重複使用與執行緒優先順序相同的 priority 欄位,而不加入額外的 memory_priority 欄位。這會產生簡化設定結構的理論,但現在如果需要不同的記憶體和排程器優先順序,就必須建立不同的設定檔物件。

正在展開 ALWAYS_NEED 提示

目前已有一個 API,可用於在 VMO 或 VMAR 上使用 ALWAYS_NEEDDONT_NEED 提示來控制復原作業。目前這些 API 僅可為對頁面支援的 VMO 做出含意,但可以延伸至對匿名 VMO 具有意義。

只擴充語意來涵蓋匿名 VMO 即可留下一些落差:

  • ALWAYS_NEED」只是提示,因此無法保證能提供未完成的回收作業。
  • 由於我們仍在追蹤年齡,因此網頁可能仍需發生存取錯誤。
  • 但無法停用頁面表格重建功能。
  • 僅適用於現有的對應。

您可以使用類似主要提案中所述的內部實作來解決這些限制,但 API 本身就有兩個基本問題。

主要提案會透過將設定檔套用至所有 VMAR (或僅限根 VMAR) 來明確得知重新啟用修復的時間。使用提示功能時,無法移除 ALWAYS_NEED,因為 DONT_NEED 的功能比復原 ALWAYS_NEED 更為強大。

使用提示 API 做為提示而非承諾的原因在於,缺少存取權控管機制,因為缺少存取權控管,可以用於任何 VMAR 或 VMO。工作政策或類似工作政策可用來控管提示的用途,但也必須設計這類機制。