RFC-0198:Magma API | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 適用於 GPU 和其他運算加速器的驅動程式 API 設計。 |
更小鳥 | |
作者 | |
審查人員 | |
提交日期 (年月分) | 2022-09-19 |
審查日期 (年-月-日) | 2022-11-01 |
摘要
Magma 是 Fuchsia 的 GPU 驅動程式庫程式設計,此架構也能用來支援其他硬體運算加速器這份 RFC 是 Magma FIDL 通訊協定的 API 設計文件。
Magma 有兩個驅動程式庫元件:載入各個應用程式的位址空間中的硬體專屬程式庫 (「用戶端驅動程式庫程式」,有時稱為「可安裝的用戶端驅動程式庫」或「ICD」);以及與硬體連接的 Magma 系統驅動程式庫。兩個「驅動程式」之間的通訊是由 Magma 通訊協定定義。
在本文件中,「應用程式」代表使用由用戶端驅動程式庫程式公開的 API 的軟體元件。
提振精神
Magma API 提供解決方案,解決在 Fuchsia 系統上支援硬體加速圖形和運算 API (主要為 Vulkan) 的問題。其 API 概念並非 Vulkan 使用,因此能減少支援其他用戶端 API (例如影片 VA-API 和 OpenVX 和 OpenCL 等用戶端 API) 的阻礙。
Magma 的設計旨在用於實作 Vulkan API。Vulkan 是 Fuchsia SDK 中的 C 樣式 ABI。這些實作 (簡稱「ICD」) 通常是由硬體廠商開發,因為加速器硬體規模龐大且複雜,因此要建構實作項目需要對硬體程式設計的相關詳細知識。
由於應用程式可能會直接使用 Vulkan,因此 ICD 是系統提供的程式庫,但無法存取硬體。使用 Magma 時,ICD 可能會透過加速器硬體連接加速器硬體,以滿足 Vulkan API 的需求,而 Vulkan API 主要包含執行用戶端定義的程式。
Magma 系統驅動程式 (「MSD」) 會在硬體上排程及執行用戶端要求,藉此實作這個通訊協定的伺服器端。因此,Magma 主要用於連結 ICD 和 MSD,以與 Linux 上的 DRM (直接轉譯管理工具) 相近的角色。
Magma 的目標是透過實際工作,將 API 中廠商的特定方面降到最低。如此一來,就能更輕鬆地考量 API 安全性,並促進驅動程式的安全性稽核。
Magma 不會讓每個 GPU 廠商自行設計 ICD-MSD 介面 (通常在 Linux 上就是如此),而是提供一系列通常需要用到的 API 功能和方法,在必要情況下,Magma 允許供應商專屬的查詢和指令結構。供應商細節不在 Magma 定義中,但驅動程式庫專屬說明文件有詳細說明。
支援螢幕硬體並非首要之務。
Magma API 目前由三個實際工作環境中的驅動程式使用中。這些用戶端驅動程式的建構和發布程序相當複雜,因為 Fuchsia SDK 中不提供此 API。
在所有目前情況下,系統都會使用用戶端程式庫,以便與 C 程式碼集進行整合 (C 是 Mesa 中的偏好語言,這種語言提供許多開放原始碼圖形驅動程式),並且提供便利的抽象層,可用於虛擬化。我們日後會檢閱 SDK,並可能納入用戶端程式庫。
相關人員
講師:
無
審查者:
jbauman@、rlb@:硬體圖形
諮詢時間:
API 委員會
社會化:
無
設計
Magma 有三種通訊協定,定義如下:
https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/sdk/fidl/fuchsia.gpu.magma/magma.fidl
部分名稱有數字後置字元 (例如 BufferRangeOp2);數字是通訊協定演變的詳細內容,因此可以忽略。
- 裝置
在 Fuchsia 啟動序列期間,對於每個能夠加快圖形及/或運算功能的實體裝置,Magma 系統驅動程式庫程式會例項化。取得適當的應用程式權限後,用戶端可能會掃描是否有一或多個「gpu」類別裝置,並開啟這些裝置。同步查詢可透過裝置通訊協定執行,取得參數,協助應用程式決定要使用哪些實體裝置。查詢參數也能用來判斷每部 GPU 裝置與哪些類型的 ICD 相容。驅動程式庫專屬和裝置專用通訊協定的確切行為取決於這些查詢參數。
當應用程式宣告其意圖來搭配特定實體裝置使用時,系統會建立與 Magma 系統驅動程式庫的連線。舉例來說,Vulkan 的意圖就是透過呼叫 vkCreateDevice() 表示使用實體裝置。用戶端驅動程式庫和系統驅動程式庫之間所有後續通訊的基底,便是這項連線的基礎。
連線由兩個頻道組成。主要管道適用於主要通訊協定,大多採用用戶端伺服器方向,另一個管道則用於從伺服器傳送至用戶端的通知。
- Primary
主要通訊協定包含採用動態饋給前期設計的少數核心功能。如果出現錯誤,就會觸發通知訊息,然後關閉連線管道。
a) 匯入共用資源、緩衝區和事件 (ImportObject、ReleaseObject)
緩衝區是 Zircon VMO 支援的共用記憶體物件。Zircon 事件可能會用於同步處理作業,在 API 預期接受半數派的情況下。
物件會由用戶端分配並由其 KOID (核心物件 ID) 參照。用戶端分配是動態饋給導向設計選項。這是假設所有緩衝區來自系統記憶體,行動裝置類別硬體通常為 true。
日後如對具有專屬記憶體的電腦類別 GPU 的支援,可能需要變更 API。
日後如要支援外部 Vulkan 時間軸區隔馬,可能需要匯入新的核心物件類型。
b) 對應緩衝區 (MapBufferGpu、UnmapBufferGpu、BufferRangeOp)
如要讓硬體能夠存取,必須將緩衝區對應至裝置位址空間。每個用戶端連線都有一個私人 GPU 位址空間 (請參閱「安全性與隱私權」一節),因此 Magma 預期要由用戶端管理裝置位址空間。
對部分驅動程式而言,MapBufferGpu 可能暗示裝置 MMU 中的分頁表格填入資料,而對某些驅動程式而言,系統則支援透過緩衝區範圍運算,明確控制網頁資料表填入。
頁面表格人口隱含緩衝區頁面的修訂版本。任何用戶端頁面解壓縮作業都應透過適當的去填入作業,與系統驅動程式協調。
c) 建立執行背景資訊 (CreateContext、DetroyContext)
如要在硬體上執行工作,需要背景資訊。Context 包含將多個結構定義轉移到硬體上所需的所有硬體狀態,並且由 Magma 系統驅動程式庫程式安排執行。Magma 針對每次連線支援多個背景資訊;這可讓多項背景資訊共用單一位址空間。
d) 執行命令 (ExecuteCommand、ExecuteImmediateCommands)
指令包含供應商專屬資料,這些資料可以修改硬體狀態,並在加速器的運算核心上執行程式碼。程式程式碼是由應用程式提供給用戶端驅動程式庫,通常採用與機器無關的格式 (例如 SPIR-V)。用戶端驅動程式庫必須將程式碼轉譯為加速器硬體能夠理解的機器層級指示。
Magma 提供兩個介面執行指令:
ExecuteCommand 會假設程式碼和相關資源包含在共用緩衝區中。系統會提供同步處理作業,其中包含一份等候指標清單,這些事件必須在工作排程前發出訊號,以及在指令完成後發出信號的信號樹狀圖。
ExecuteImmediateCommands 以內嵌方式傳送指令。如果驅動程式庫定義了分割方式,則單一管道訊息中可能包含多個指令。目前每則訊息的指令位元組數上限為 2,000;目前長度良好,但不允許有效使用完整管道訊息大小。視相關的指令資料而定,系統會提供「階段馬」做為等待或信號。
日後提交指令時應考量下列因素:將 fuchsia.mem.Data 與臨時 VMO 搭配使用,或 Linux「io_uring」等模型:https://en.wikipedia.org/wiki/Io_uring
e) 流量控制
為避免用戶端將過多訊息推送至主要管道,同時避免主要管道中待匯入的緩衝區物件過度使用記憶體,裝置通訊協定會發布值上限,而主要通訊協定會規定用戶端保留數量,然後延遲傳送訊息,使這些訊息數低於發布上限。伺服器會提供事件訊息,通知用戶端計數可能會減少的時間。
f) 效能計數器
主要通訊協定會公開許多專門用於與硬體計數器互動的 API,對應用程式而言,這些 API 是為了讓應用程式能夠深入瞭解在加速器硬體上執行的程式的行為和效能特性。
- 通知
通知管道適用於僅透過反向 (伺服器-用戶端) 方向傳送的訊息,通常是回應指令完成狀態。通知訊息的內容會因供應商而異,因此已定義空白的通訊協定。
與主要管道分開的通知管道可讓用戶端更輕鬆地處理通知事件,例如,用戶端可能會使用專屬執行緒。在主要管道上,用戶端呼叫可能來自多個執行緒,也就是沒有任何執行緒在非同步調度工具中輪詢,而我們不希望基於效能因素將這些呼叫代理至主要管道。這會導致讀取非同步事件困難 (除了在傳送訊息時只需要讀取的流程控制事件除外)。
不明
目前有四種支援的 Magma 驅動程式 (實際工作環境中的三項),另外兩種則是原型設計。整合每個額外 Magma 驅動程式庫後,即可進一步瞭解 Magma 通訊協定是否適合取代各種現有 Linux 型用戶端驅動程式庫程式核心驅動程式庫程式介面。新增對電腦類別 GPU 的支援,可讓核心 API 與各種硬體相容。
主要有待改進的 API 領域:指令執行和通知處理。
我們非常歡迎 API 委員會的意見回饋,特別是以下主題:
a) API 與其他 Fuchsia API 的相似或相異之處 b) 是否有機會讓 API 更符合未來趨勢? c) 對於 Fuchsia 適用的 io_uring 模型實用性有什麼看法?
Google 的網域專家已迅速審核這個 API,但若能進一步審查 Google 專家/其他相關團隊的深入審查結果,可能對您有幫助。
效能
裝置通訊協定包含同步方法,但只能在應用程式的設定階段使用。主要通訊協定包含非同步方法,而且會在通知管道上以非同步方式傳回指令完成項目。
大多數資料都會在 VMO 中共用,因此資料複製作業會大幅減少。建立和對應緩衝區可能很慢,但假設應用程式設計良好 (例如執行記憶體子配置),這些作業應該很少發生。
在大多數情況下,我們評估了 Magma 驅動程式在 Fuchsia 上的效能,與在相同硬體的 Linux 上執行的相同用戶端驅動程式庫程式碼集相同。
人體工學、可用性
這個 API 設計與已經過研究的現有以 Linux 為基礎的用戶端驅動程式庫程式核心驅動程式庫程式介面類似,但配置作業會盡可能在用戶端執行。
我們認為 API 的語意合理直觀,因為這個 API 已使用兩年的時間、在這段期間已修訂,目前正從不同廠商在實際工作環境中提供三個驅動程式。
日後,系統可能會視 Vulkan 時間軸賽馬使用新的核心物件;如果符合的話,可將其新增至 ObjectType,而在執行 API 中由 KOID 指定樹狀圖,系統可能會改為參照「timeline」物件來取代事件。
回溯相容性
許多未來預期擴充能力的平台都使用 FIDL 資料表。
安全性
Magma API 可讓應用程式在重要的共用系統資源上執行未經驗證的程式,因此安全性是個重要主題。安全性審查已於 2021 年 6 月完成:詳情請參閱 https://fxbug.dev/42146613。
用戶端可以提交長時間執行的程式,拒絕其他用戶端存取硬體。與其他系統的行為類似,Magma 系統驅動程式庫會確保長時間執行的程式會以系統中斷程度的「可接受」狀態取消。
圖形記憶體可能包含密碼等機密資訊,因此請務必隔離用戶端的記憶體存取權。用戶端連線會透過獨立的硬體位址空間彼此隔離,也就是說,用戶端程式只能存取已匯入連線的記憶體緩衝區 (由用戶端建立,或明確從外部接收)。這種方法可能會產生潛在的硬體安全漏洞。
用戶端數量可能會超過硬體提供的位址空間數量。MSD 應安排對這些資源的存取權或完全拒絕用戶端。
基於效能考量,驗證用戶端指令和程式並不實際,因此硬體必須具有彈性。
隱私防護
查詢 DEVICE_ID 提供的裝置 ID 通常不會重複。
效能計數器事件可用來判斷系統上其他工作負載的詳細統計資料組合,以用來收集其他程序正在執行的指紋。因此,這些 API 比大多數 Magma API 更多,並且僅限於可存取 /dev/class/gpu-performance-counters 裝置的組合程序。
測試
這裡提供一個簡單的 API 功能測試:
https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/graphics/lib/magma/tests/integration/test_magma_fidl.cc
在不加入硬體細節的情況下,編寫更複雜的測試來練習 Magma API,可能並不容易。用戶端驅動程式庫程式碼包含這些硬體程式設計詳細資料,因此,執行用戶端驅動程式所公開 API 的測試套件至關重要。
Vulkan 合法性測試通過持續整合測試,適用於兩個正式版 Magma 驅動程式。OpenVX 一致性測試會在機器學習的 Magma 驅動程式上執行,
請注意,在建構 Magma 驅動程式庫時,開發人員必須建構可實作 Magma 通訊協定伺服器端功能運作的 Magma 系統驅動程式庫,才能測試使用 Magma API 的用戶端驅動程式庫程式程式碼。
說明文件
文件符合 FIDL 定義。
缺點、替代項目和未知
這項設計與 Vulkan 同步,旨在盡可能降低驅動程式庫負擔,並最大化系統圖形效能。這項設計的缺點是,基於安全性考量,其仰賴大量硬體,而替代設計則可能會嘗試提供用戶端指令驗證。不過,驗證作業既複雜又不完美,卻可能代價高昂的效能。
優先藝術與參考資料
Linux GPU 驅動程式開發人員指南:https://www.kernel.org/doc/html/v4.18/gpu/index.html