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 和 Controller 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 多重處理,因此用戶端可以使用類型管道。
驅動程式架構不會在連線至裝置時提供 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,因此效能可能會略為提升。
人體工學
驅動程式架構可能會決定新增輔助程式庫,以便連線至控制器 API。這會取決於前幾次遷移作業。
如果用戶端嘗試在裝置上呼叫不明的 FIDL 通訊協定,驅動程式架構也會更新,以便記錄錯誤。也就是說,如果用戶端仍錯誤地依賴多重處理,就會產生錯誤記錄。很抱歉,要將錯誤記錄正確歸因於特定客戶並不容易。
回溯相容性
無法移除 FIDL 多工處理功能,並保留回溯相容性。
安全性考量
這項提案沒有任何安全性考量。這項工作可讓用戶端行為更明確且易於理解,進而稍微提升 devfs 的安全性。
日後,驅動程式架構將會限制對 fuchsia.device/Controller
的存取權。舉例來說,如果用戶端可以存取 /dev/class/input-report
,就不需要存取控制器通訊協定。限制這項功能可提升安全性,而移除 FIDL 多工處理功能可讓驅動程式架構在日後限制這項功能。限制此通訊協定的實際計畫不在本 RFC 的範圍內,可做為後續專案。
隱私權注意事項
這項提案沒有隱私權考量。
測試
我們會測試允許清單和移除多重處理的驅動程式架構功能。
每次移除許可清單都必須依賴 CQ 中現有的測試涵蓋率。由於這項多工處理作業是在 FIDL 類型系統之外發生,因此沒有很好的方法可以靜態判斷哪些用戶端會依賴多工處理行為。
說明文件
我們已新增開放專案頁面形式的說明文件,其中概略說明瞭允許清單、動機和更新步驟。專案完成後,沒有任何用戶端會依賴這項行為,因此不需要提供相關文件。
缺點、替代方案和未知事項
在 DFv2 中使用服務功能
目前主要的替代做法是等待「驅動程式做為元件」(DFv2) 的努力完成,然後直接將用戶端遷移至使用服務功能。
不過,必須先在所有可能的電路板上啟用 DFv2,才能開始將用戶端遷移至服務功能。在此期間,我們會新增更多依賴多重處理的用戶端,包括更難遷移的樹狀結構外用戶端。此外,DFv1 相容性墊片需要支援 FIDL 多工處理,才能保留現有行為,而將自身匯出至 devfs 的 DFv2 驅動程式也需要支援多工處理。從 DFv1 移除這項技術債務,將可簡化 DFv2 設計,而不需要將這項技術債務帶入。
如果用戶端同時需要解開 FIDL 多工處理,將用戶端移至服務功能會更加困難。如果一次只修正一個問題,這些遷移作業就能更快速地進行。
既有技術與參考資料
FIDL 已概略說明通訊協定的最佳做法。