RFC-0223:zx_vmo_transfer_data

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

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

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

摘要

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

提振精神

過去對 Fuchsia 效能的分析發現,Bootfs 的深層階層式 CoW 複製鏈,會導致在查詢頁面時搜尋時間過長。這個系統呼叫會將複製鏈結替換為含有 Bootfs 個別項目的「拼接」VMO,藉此減少這項額外負擔。

雖然目前是為了 Bootfs,但未來可能會有其他情況,需要移動頁面才能提升效能。

利害關係人

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

導師:cpu@

審查者:rashaeqbal@、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 移至 [offset, offset + length) (位於 dst_vmo 中)。這在功能上等同於從 src_vmodst_vmomemmove,然後取消認可 src_vmo 中相關聯的頁面。不過,達成這項作業的機制不同,因為系統實際上是在 VMO 之間移動支援頁面,而不是複製資料。進而大幅提升效能。儘管機制不同,這個系統呼叫的語意與 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_STATE:將 src_vmodst_vmo 中指定範圍內的頁面釘選。
  • ZX_ERR_NOT_SUPPORTEDsrc_vmodst_vmo 是實體、連續或分頁支援的 VMO。我們日後或許可以支援分頁支援的 VMO。
  • ZX_ERR_OUT_OF_RANGEdst_vmosrc_vmo 中指定的範圍無效。
  • ZX_ERR_NO_MEMORY:記憶體不足,導致失敗。

實作

這應該是一組相對簡單的 CL,因為我們現有的系統呼叫 zx_pager_supply_pages 針對分頁支援的 VMO 執行非常類似的作業。因此,我們可以重複使用許多支援該系統呼叫的程式碼。 不過,我們需要進行幾項變更,才能支援這項新用途:

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

效能

我們預期這項做法可大幅提升 Bootfs 中的 VMO 頁面查閱效能。 具體來說,從目前使用的 CoW 複製鏈切換為使用這個系統呼叫移動頁面,應該可以將啟動檔案系統查閱作業的效能提升約 20%。請注意,如果建立 VMO 的副本,而不是像這個系統呼叫建議一樣移動頁面,我們就能獲得類似的啟動檔案系統查閱改善項目。不過,這種做法會導致系統啟動時間最多倒退 70% (視執行的硬體目標而定)。使用這項 RFC 建議的方法,可彌補大部分的迴歸。

回溯相容性

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

安全性考量

我們預期這項提案不會造成任何安全疑慮,因為新作業在功能上與現有作業 (memcpy() + uncommit) 相同,但效能更佳。這項功能並非要讓程序執行原本無法執行的動作。

但這會擴大攻擊面。如果系統呼叫實作項目中存在可供利用的錯誤,任何程序都可能加以利用。

隱私權注意事項

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

測試

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

說明文件

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

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

我們可以將 zx_pager_supply_pages 歸納為適用於匿名 VMO。這會大幅增加該系統呼叫的實作複雜度,而且可能仍需要修改 API,才能接受匿名 VMO 做為輸入內容。

如果我們的唯一目標是提升啟動檔案系統中 CoW 複製階層的頁面查閱效能,也可以只使用 VMO 副本,不必建立 CoW 副本。不過,由於額外的複製作業負擔,這會大幅降低啟動時間。