RFC-0223:zx_vmo_transfer_data

RFC-0223:zx_vmo_transfer_data
狀態已接受
區域
  • 核心
說明

推出名為 zx_vmo_transfer_data 的新系統呼叫,可有效率地將資料從一個 VMO 移至另一個 VMO。

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2023-05-22
審查日期 (年-月-日)2023-08-14

摘要

我們建議新增新的系統呼叫 zx_vmo_transfer_data,讓呼叫端可將網頁從一個 VMO 移至另一個 VMO。這可以視為效率提升,可讓您移動資料,而不會產生複製的額外負擔。

提振精神

過去對 Fuchsia 效能進行的分析發現,Bootfs 的 CoW 深層階層鏈結會導致查詢網頁時搜尋時間過長。這個系統呼叫會將複本鏈結替換為含有 Bootfs 個別項目的「拼接」VMOs,藉此減少這項開銷。

雖然 Bootfs 是目前的動機,但未來可能會有其他情況,可透過移動頁面來改善效能。

相關人員

誰會受到這項 RFC 是否通過的影響?(此為選用部分,但建議您填寫)。

導師:cpu@

審查者:rasheqbal@, jamesr@

諮詢對象:mcgrathr@、maniscalco@、adanis@、eieio@

社交化:這項提案以單頁文件的形式向 Zircon 團隊進行社交化。

設計

我們會將下列系統呼叫新增至 Zircon 系統呼叫 API:

zx_status_t zx_vmo_transfer_data(zx_handle_t dst_vmo,
                                 uint32_t options,
                                 uint64_t offset,
                                 uint64_t length,
                                 zx_handle_t src_vmo,
                                 uint64_t src_offset);

其中:

  • dst_vmo 是目的地 VMO 的控制代碼。此帳號代碼必須具備 ZX_RIGHT_WRITE
  • options 是目前未使用的欄位,可用於日後擴充 API。
  • offset 是頁面移至目的地的偏移量。
  • length 是移動至目的地的位元組數。
  • src_vmo 是來源 VMO 的控制代碼。這個帳號代碼必須具備 ZX_RIGHT_READZX_RIGHT_WRITE
  • src_offset 是從來源擷取網頁的偏移量。

這個系統呼叫會將 [src_offset, src_offset + length) 中的頁面從 src_vmo 移至 dst_vmo 中的 [offset, offset + length)。在功能上,這等同於從 src_vmodst_vmomemmove,接著在 src_vmo 中取消提交相關網頁。不過,實現此功能的機制有所不同;實際上,備用頁面會在 VMOs 之間移動,而非複製資料。這麼做可大幅提升效能。儘管機制不同,這個系統呼叫仍會提供與 memmove 相同的語意,也就是支援提供重疊的來源和目的地區域。

讀者可能會好奇,為何系統呼叫 zx_vmo_transfer_data 而非 zx_vmo_transfer_pages 時,系統會移動頁面。這是我們刻意做出的選擇,以便日後放寬嚴格的網頁對齊要求。舉例來說,我們可能會支援使用者要求轉移一頁半的用途。在這種情況下,我們會移動第一頁,然後複製剩下的半頁。這比使用者單純複製的效率更高,因為我們可以略過目標網頁的零值。請注意,初始實作不支援此用途;這裡提到這項用途,只是為了提供命名選項的背景資訊。

系統會覆寫目的地範圍內的現有頁面。目的地 VMO 的所有對應項目也會顯示新內容。如果目的地 VMO 有兒童,兒童的類型會影響兒童看到的內容。ZX_VMO_CHILD_SNAPSHOTZX_VMO_CHILD_SNAPSHOT_MODIFIED 類型的子項會繼續顯示舊內容。所有其他類型的兒童都會看到新內容。遷移完成後,src_vmo 中的頁面會歸零。

移動作業可能會因各種原因而失敗。如需可能的錯誤代碼和傳回這些代碼的情況完整清單,請參閱下方的錯誤一節。

如果遷移作業失敗,src_vmo VMO 中的任一網頁可能已遷移至 dst_vmo。我們無法保證確切移動了多少資料。不過,我們可以保證在符合下列條件時,呼叫會成功:

  1. 未符合下列任何可能導致錯誤的條件。
  2. 在執行此作業期間,任何其他執行緒都不會修改 src_vmodst_vmo

在此情況下,「修改」是指直接對 VMO 或 VMO 參照項目 (例如切片、參照子項等) 進行寫入/調整大小/固定的動作。修改任何類型快照的上層、子項或同層項目,不應導致任何錯誤,但視快照而定,您可能會遇到寫入撕裂現象。如果您操控 SNAPSHOT_AT_LEAST_ON_WRITE VMO 的父項,可能會發生寫入撕裂現象,因為實際轉移作業並未保證原子性。請注意,如果要從 SNAPSHOT 子項轉移網頁,我們可能需要執行複製作業,也就是說,如果該特定網頁尚未執行「寫入時複製」作業,就必須分配新的網頁。

以下是這個系統呼叫可能傳回的錯誤及其含義:

  • ZX_ERR_BAD_HANDLEsrc_vmodst_vmo 不是有效的 VMO 句柄。
  • ZX_ERR_INVALID_ARGSoffsetlengthsrc_offset 未對齊頁面。如先前所述,我們可能會在日後移除這項限制。
  • ZX_ERR_ACCESS_DENIEDsrc_vmo 沒有 ZX_RIGHT_WRITEZX_RIGHT_READ,或是 dst_vmo 沒有 ZX_RIGHT_WRITE
  • ZX_ERR_BAD_STATEsrc_vmodst_vmo 中指定範圍內的頁面會固定。
  • ZX_ERR_NOT_SUPPORTEDsrc_vmodst_vmo 是實體、連續或 pager 支援的 VMOs。我們日後或許可以支援使用 pager 的 VMOs。
  • ZX_ERR_OUT_OF_RANGEdst_vmosrc_vmo 中指定的範圍無效。
  • ZX_ERR_NO_MEMORY:記憶體不足導致失敗。

實作

這應該是相對簡單的 CL 集合,因為我們有現有的系統呼叫 zx_pager_supply_pages,可為 pager 支援的 VMOs 執行類似的操作。因此,我們可以重複使用許多支援該系統呼叫的程式碼。不過,我們需要進行幾項變更,才能支援這個新用途:

  1. zx_pager_supply_pages 會驗證提供的 VMO 是否由指定的 pager 物件支援。這項功能必須在新系統呼叫中移除。
  2. SupplyPageszx_pager_supply_pages 用於將頁面插入 VMO 的函式,會假設分頁器的存在,在程式碼中稱為 page_source_。我們必須移除這項假設,方法是在對 page_source_ 執行作業之前,先加入空值檢查,並移除任何關於其存在的斷言。
  3. SupplyPages 也會在將頁面拼接至目的地之前,解壓縮所有已壓縮的頁面並新增標記,因為它預期目的地會由分頁器支援。這項功能對匿名 VMOs 並非必要,因此我們需要根據目的地是否有 pager 支援來決定是否啟用。
  4. SupplyPages 目前會略過目標中存在的任何網頁,但仍會釋放來源中的網頁。如先前所述,我們會將這項設定變更為一律覆寫目的地。
  5. SupplyPages 目前不會計算有父項的 VMOs。在大多數情況下,這不會造成任何問題。不過,如果目的地是 ZX_VMO_CHILD_SNAPSHOT 類型的子項,我們就需要更新父項中的分割位元,以表示 VMO 已從隱藏的父項分離。

成效

我們預期這項功能可大幅改善 Bootfs 中的 VMO 網頁查詢效能。具體來說,從目前使用的 CoW 複本鏈結切換至使用此系統呼叫移動頁面,可使啟動檔案系統查詢提升約 20%。請注意,我們可以透過建立 VMOs 副本,而非移動頁面 (如這個系統呼叫所建議),來獲得類似的啟動檔案系統查閱改善效果。不過,這種做法確實可將系統的啟動時間縮短最多 70% (視執行的硬體目標而定)。使用此 RFC 提出的方法可回復大部分的回歸。

回溯相容性

我們不會移除現有的 zx_pager_supply_pages 系統呼叫,因此不會造成任何回溯相容性問題。

安全性考量

我們不預期這項提案會帶來任何安全性影響,因為新作業的功能與現有作業 (memcpy() + uncommit) 相同,但效能更佳。這並非為了讓程序執行原本無法執行的動作。

不過,這會增加攻擊面。如果系統呼叫導入程序中存在可供利用的錯誤,任何程序都可能會利用這些錯誤。

隱私權注意事項

我們不認為這項提案會對隱私權造成任何影響。

測試

我們會新增可利用新系統呼叫的核心測試,並驗證上述所有行為 (頁面移動、限制和來源頁面歸零)。我們也會新增基準,用來評估這個系統呼叫的效能,以便與副本的效能進行比較。

說明文件

我們會新增說明 zx_vmo_transfer_data 的新文件。

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

我們可以將 zx_pager_supply_pages 泛用化,以便與匿名 VMOs 搭配使用。這會大幅增加該系統呼叫的實作複雜度,且可能仍需要修改 API,才能接受匿名 VMOs 做為輸入內容。

如果我們的唯一目標是改善啟動檔案系統中 CoW 複本階層中的網頁查詢效能,我們也可以只使用 VMO 的副本,而非建立 CoW 複本。不過,由於需要額外的複製作業,因此會大幅延遲啟動時間。