RFC-0213:移除 devfs FIDL 多重作業

RFC-0213:移除 devfs FIDL 多路複用
狀態已接受
區域
  • 驅動程式
說明

說明在 devfs 中移除 FIDL 多路複用的原因和計畫

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2023-03-28
審查日期 (年-月-日)2023-03-17

摘要

這項提案概述了移除 devfs 功能的程序,該功能會透過單一連線多工處理多個 FIDL 通訊協定。說明移除這項功能後,為何能解除新驅動程式庫功能的封鎖,並將驅動程式庫 FIDL 連線與 Fuchsia 的其餘部分標準化。

提振精神

驅動程式架構會管理硬體裝置和用戶端之間的連線。在過去,這項連線提供三種 FIDL 通訊協定:

  • fuchsia.io/Node
  • fuchsia.device/Controller
  • 裝置的實際 FIDL 通訊協定

這項多工處理作業需要驅動程式架構擁有管道,才能提供節點和控制器通訊協定。這樣可防止基礎驅動程式庫擁有管道。這項設計表示驅動程式架構必須在驅動程式和驅動程式主機之間維持 C FIDL 邊界。這也表示驅動程式無法區分多個連線,或儲存每個連線的狀態。這項限制導致出現許多「彈跳床通訊協定」,也就是驅動程式庫和用戶端交換一組新管道的通訊協定,目的只是為了避開多工管道。

這種多路複用違反了 FIDL 的組合設計原則。FIDL 設計原則指出,通訊協定在編譯時可以是多個通訊協定。composed不過,驅動程式架構會在執行階段進行這項組合,且無法辨識裝置使用的 FIDL 通訊協定。在執行階段多工處理時,也可能會在多工處理的通訊協定中發生序數衝突。

由於控制器通訊協定採用多路複用技術,因此無法使用能力轉送來限制 fuchsia.device/Controller 的存取權。舉例來說,/dev/class/input-report的用戶端大多想存取fuchsia.input.report/Device。不過,fuchsia.device/Controller 是在同一個管道中提供服務,因此您能夠取消繫結、重新繫結或設定這些裝置的電源狀態。如果裝置的 FIDL 和控制器 FIDL 多工處理於同一管道,就無法解決這個路由問題。

程式碼集會使用 Node 通訊協定的多路複用功能,複製裝置的連線。雖然複製裝置連線的概念不錯,但底層驅動程式庫並不知道這項能力。此外,fuchsia.io/Node.Clone 的 API 會接收 fuchsia.io/Node 的伺服器端,因此使用這個 API 複製裝置的管道會謊報管道的基礎類型。目前有大量用戶端程式碼會執行這項操作,方法是直接呼叫 FIDL 或使用檔案描述元。Fuchsia 已建立使用型別通道的最佳做法,我們應在這個領域強制執行這些最佳做法。

利害關係人

協助人員:

  • abarth

審查者:

  • abarth
  • cja
  • csuter
  • surajmalhotra
  • tamird
  • yifei

已諮詢:

社交:

這份 RFC 最初是設計文件,並經過 Driver Framework 團隊的設計審查。

需求條件

這些規定分為兩類:遷移和最終狀態。

遷移

遷移計畫必須是軟性遷移,並設有允許清單。Fuchsia 包含大量與驅動程式庫用戶端互動的程式碼,包括樹狀結構內和樹狀結構外的程式碼。無法一次從所有 devfs 移除多工。 如果允許清單中包含個別工作,我們就能逐步完成遷移作業,並防止遷移作業倒退。

遷移作業應盡可能採用機械式方法。每次更新用戶端時,都應盡量簡化,讓不熟悉驅動程式或驅動程式庫程式架構的人也能執行遷移作業。更新越機械化,遷移速度就越快。

結束狀態

裝置連線必須明確。用戶端要求裝置控制器或基礎裝置通訊協定時,應清楚說明。不會有 FIDL 多路複用,因此用戶端可以使用型別通道。

Driver Framework 不會在連線至裝置時提供 fuchsia.io/Node

司機將可自行與客戶建立連結,移除 FIDL 多工處理後,還會進行另一次遷移,將驅動程式移至 DDK API,以便在用戶端嘗試連線時,為驅動程式庫提供管道。這項遷移作業完成後,驅動程式就能擁有每個連線的狀態,並使用 Fuchsia 程式碼庫其餘部分使用的 FIDL 繫結。

設計

正在連線至 fuchsia.device/Controller

如要連線至 fuchsia.device/Controller,用戶端必須在 devfs 檔案系統中開啟特定節點。這個節點會命名為 device_controller,並同時位於 devfs 類別路徑和 devfs 拓撲路徑中。

如果用戶端是從 /dev/class/input-report/abcd 控制器取得裝置通訊協定,則該通訊協定會位於 /dev/class/input-report/abcd/device_controller

如果用戶端是從 /dev/sys/platform/pci/00:12 控制器取得裝置通訊協定,則該通訊協定會位於 /dev/sys/platform/pci/00:12/device_controller

從 /dev/class/ 移除多工

devfs 類別路徑會有兩個允許清單:一個用於 fuchsia.io/Node,另一個用於 fuchsia.device/Controller。這些允許清單會列出仍多工處理相關通訊協定的 /dev/class/{protocol} 名稱。

用戶端更新完畢,不再依賴多工行為後,系統就會移除許可清單中的項目。

從拓撲路徑中移除多工

如果從許可清單中移除類別路徑的項目,拓撲路徑中對應的項目也會移除多工處理。

舉例來說,如果 /dev/class/input-report 移除了 fuchsia.io/Node,對應這些輸入裝置的拓撲路徑也不會再提供 fuchsia.io/Node

實作

允許清單會在驅動程式庫架構中實作。從許可清單中移除項目時,必須更新依賴這項多工處理的用戶端。

效能

移除 FIDL 多路複用功能後,效能應該不會受到顯著影響。由於 FIDL 訊息不需要嘗試分派至節點或控制器 API,因此效能可能會略有提升。

人體工學

Driver Framework 可能會決定新增輔助程式庫,以便連線至 Controller API。這取決於前幾次遷移作業。

如果用戶端嘗試在裝置上呼叫不明 FIDL 通訊協定,驅動程式架構也會更新,以便記錄錯誤。也就是說,如果用戶端仍錯誤地依賴多路複用,就會產生 ERROR 記錄。很抱歉,我們無法輕易將錯誤記錄正確歸因於特定用戶端。

回溯相容性

無法移除 FIDL 多路複用,同時保留回溯相容性。

安全性考量

這項提案沒有任何安全性考量。這項工作可能會稍微改善 devfs 的安全性,讓用戶端行為更明確且容易理解。

日後,Driver Framework 會限制對 fuchsia.device/Controller 的存取權。 舉例來說,如果用戶端可存取 /dev/class/input-report,就不需要存取控制器通訊協定。限制這項功能可提升安全性,移除 FIDL 多路複用功能後,驅動程式架構日後就能限制這項功能。限制這項通訊協定的實際計畫不在本 RFC 的範圍內,可視為後續專案。

隱私權注意事項

這項提案不涉及隱私權考量。

測試

我們將測試允許清單的驅動程式架構功能,以及移除多路複用功能。

很遺憾,每次移除許可清單都必須依賴 CQ 中的現有測試涵蓋範圍。由於這種多工處理是在 FIDL 型別系統之外進行,因此無法靜態判斷哪些用戶端依賴多工處理行為。

說明文件

我們已新增開放專案頁面形式的文件, 這個頁面會列出允許清單、動機和更新步驟。專案完成後,不會有任何用戶端依賴這項行為,因此不需要任何文件。

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

在 DFv2 中使用服務功能

目前的主要替代方案是等待驅動程式完成元件 (DFv2) 作業,然後直接將用戶端遷移至使用服務功能

不過,必須先在所有可能的開發板上啟用 DFv2,才能開始將用戶端遷移至服務功能。同時,我們也會新增更多依賴多路複用的用戶端,包括更難遷移的樹狀結構外用戶端。此外,DFv1 相容性墊片必須支援 FIDL 多路複用,才能保留現有行為,而匯出至 devfs 的 DFv2 驅動程式也必須支援多路複用。從 DFv1 移除這項技術債,可簡化 DFv2 設計,而不必將這項技術債延續到 DFv2。

如果用戶端也需要同時解除 FIDL 多路複用,將用戶端移至服務功能會更加困難。一次修正一個問題,可加快遷移速度。

既有技術和參考資料

FIDL 已列出通訊協定組合的最佳做法