Windows 圖形顯示驅動開發-WDDM 2.4功能-基于 IOMMU 的 GPU 隔離(三)

幀緩沖區保留

對于必須在電源轉換期間將幀緩沖區的保留部分保存到系統內存的驅動程序,Dxgkrnl 會在適配器初始化時對所需內存進行用量認可。 如果驅動程序報告 IOMMU 隔離支持,則 Dxgkrnl 將在查詢物理適配器上限后立即調用 DXGKDDI_QUERYADAPTERINFO,內容如下:

  • Type 為 DXGKQAITYPE_FRAMEBUFFERSAVESIZE
  • 輸入類型為 UINT,即物理適配器索引。
  • 輸出類型為 DXGK_FRAMEBUFFERSAVEAREA,應為驅動程序在電源轉換期間保存幀緩沖區保留區域所需的最大大小。

Dxgkrnl 會按驅動程序指定的數量進行用量認可,以確保始終能根據請求獲取物理頁面。 此操作是通過為每個物理適配器創建一個唯一的區域對象來完成的,該對象為最大尺寸指定了一個非零值。

驅動程序報告的最大大小必須是 PAGE_SIZE 的倍數。

與幀緩沖區之間的傳輸可以在驅動程序選擇的時間進行。 為了幫助傳輸,Dxgkrnl 向內核模式驅動程序提供了上表中的最后四個回調。 這些回調可用于映射適配器初始化時創建的區域對象的相應部分。

在調用這四個回調函數時,驅動程序必須始終為 LDA 鏈中的主導設備提供 hAdapter。

驅動程序有兩個實現幀緩沖區保留的選項:

  • (首選方法)驅動程序應使用 DXGKDDI_QUERYADAPTERINFO 來調用為每個物理適配器分配空間,以指定每個適配器所需的存儲空間。 在電源轉換時,驅動程序應每次保存或恢復一個物理適配器的內存。 此內存會被分割成多個區域對象,每個物理適配器一個。
  • ?(可選)驅動程序可以將所有數據保存或還原到單個共享區域對象中。 要執行此操作,可在 DXGKDDI_QUERYADAPTERINFO 調用中為物理適配器 0 指定一個較大的最大大小,然后為所有其他物理適配器指定一個零值。 這樣,驅動程序就可以將整個區域對象固定下來,供所有物理適配器的所有保存/還原操作使用。 這種方法的主要缺點是需要一次性鎖定更多內存,因為它不支持只將內存的子范圍固定到 MDL 中。 因此,在內存壓力下,這種操作更容易失敗。 此外,驅動程序還應使用正確的頁面偏移量將 MDL 中的頁面映射到 GPU。

?驅動程序應執行以下任務,以完成向幀緩沖區或從幀緩沖區的傳輸:

  • 在初始化過程中,驅動程序應使用其中一個分配回調例程預先分配一小塊 GPU 可訪問內存。 如果無法一次性映射/鎖定整個區域對象,則使用該內存來幫助確保向前推進。

  • 在電源轉換時,驅動程序應首先調用?Dxgkrnl?以固定幀緩沖區。 成功后,Dxgkrnl?會為驅動程序提供一個 MDL,用于鎖定映射到 IOMMU 的頁面。 然后,驅動程序就可以通過任何對硬件最有效的方式直接向這些頁面執行傳輸。 然后,驅動程序應調用?Dxgkrnl?來解鎖/取消映射內存。

  • 如果?Dxgkrnl?無法立即鎖定整個幀緩沖區,則驅動程序必須嘗試使用初始化時分配的預分配緩沖區來向前推進。 在這種情況下,驅動程序按小塊來執行傳輸。 在每次迭代傳輸過程中(針對每個區塊),驅動程序必須要求?Dxgkrnl?提供一個可將結果復制到其中的區域對象映射范圍。 然后,驅動程序必須在下一次迭代之前取消區域對象的映射。

下面的偽代碼是實現這種算法的一個示例。

#define SMALL_SIZE (PAGE_SIZE)PMDL PHYSICAL_ADAPTER::m_SmallMdl;
PMDL PHYSICAL_ADAPTER::m_PinnedMdl;NTSTATUS PHYSICAL_ADAPTER::Init()
{DXGKARGCB_ALLOCATEPAGESFORMDL Args = {};Args.TotalBytes = SMALL_SIZE;// Allocate small buffer up front for forward progress transfersStatus = DxgkCbAllocatePagesForMdl(SMALL_SIZE, &Args);m_SmallMdl = Args.pMdl;...
}NTSTATUS PHYSICAL_ADAPTER::OnPowerDown()
{    Status = DxgkCbPinFrameBufferForSave(&m_pPinnedMdl);if(!NT_SUCCESS(Status)){m_pPinnedMdl = NULL;}if(m_pPinnedMdl != NULL){        // Normal GPU copy: frame buffer -> m_pPinnedMdlGpuCopyFromFrameBuffer(m_pPinnedMdl, Size);DxgkCbUnpinFrameBufferForSave(m_pPinnedMdl);}else{SIZE_T Offset = 0;while(Offset != TotalSize){SIZE_T MappedOffset = Offset;PVOID pCpuPointer;Status = DxgkCbMapFrameBufferPointer(SMALL_SIZE, &MappedOffset, &pCpuPointer);if(!NT_SUCCESS(Status)){// Driver must handle failure here. Even a 4KB mapping may// not succeed. The driver should attempt to cancel the// transfer and reset the adapter.}GpuCopyFromFrameBuffer(m_pSmallMdl, SMALL_SIZE);RtlCopyMemory(pCpuPointer + MappedOffset, m_pSmallCpuPointer, SMALL_SIZE);DxgkCbUnmapFrameBufferPointer(pCpuPointer);Offset += SMALL_SIZE;}}
}NTSTATUS PHYSICAL_ADAPTER::OnPowerUp()
{Status = DxgkCbPinFrameBufferForSave(&m_pPinnedMdl);if(!NT_SUCCESS(Status)){m_pPinnedMdl = NULL;}if(pPinnedMemory != NULL){// Normal GPU copy: m_pPinnedMdl -> frame bufferGpuCopyToFrameBuffer(m_pPinnedMdl, Size);DxgkCbUnpinFrameBufferForSave(m_pPinnedMdl);}else{SIZE_T Offset = 0;while(Offset != TotalSize){SIZE_T MappedOffset = Offset;PVOID pCpuPointer;Status = DxgkCbMapFrameBufferPointer(SMALL_SIZE, &MappedOffset, &pCpuPointer);if(!NT_SUCCESS(Status)){// Driver must handle failure here. Even a 4KB mapping may// not succeed. The driver should attempt to cancel the// transfer and reset the adapter.}RtlCopyMemory(m_pSmallCpuPointer, pCpuPointer + MappedOffset, SMALL_SIZE);GpuCopyToFrameBuffer(m_pSmallMdl, SMALL_SIZE);DxgkCbUnmapFrameBufferPointer(pCpuPointer);Offset += SMALL_SIZE;}}
}

硬件保留內存

在設備連接到 IOMMU 之前,VidMm 會映射硬件保留內存。

VidMm 會自動處理任何作為帶有 PopulatedFromSystemMemory 標記的內存段報告的內存。 VidMm 會根據提供的物理地址來映射該內存。

對于未通過段公開的專用硬件保留區域,VidMm 會調用 DXGKDDI_QUERYADAPTERINFO 驅動程序來查詢其范圍。 所提供的范圍不得與 NTOS 內存管理器使用的任何內存區域相重疊;VidMm 會驗證是否存在此類交叉。 此驗證可確保驅動程序不會意外報告超出保留范圍的物理內存區域,因而違反該功能的安全保證。

調用一次查詢是為了查詢所需的范圍數量,而隨后的第二次調用是為了填充保留范圍的數組。

測試

如果驅動程序選擇使用此功能,HLK 測試將掃描驅動程序的導入表,以確保沒有調用以下 Mm 函數:

  • MmAllocateContiguousMemory
  • MmAllocateContiguousMemorySpecifyCache
  • MmFreeContiguousMemory
  • MmAllocatePagesForMdl
  • MmAllocatePagesForMdlEx
  • MmFreePagesFromMdl
  • MmProbeAndLockPages

?所有連續內存和 MDL 的內存分配都應通過?Dxgkrnl?的回調接口,使用列出的函數來進行。 驅動程序也不應鎖定任何內存。?Dxgkrnl?會為驅動程序管理鎖定的頁面。 一旦重新映射了內存,提供給驅動程序的頁面邏輯地址可能不再與物理地址一致。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76313.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76313.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76313.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UML之擴展用例

UML用例建模面向業務實現或者系統功能,每一個用例實現一個完整的業務或者功能。而一個完整的用例也可能有一些不是必需的附加功能,或者在該用例已經實現后需要添加一些新功能,此時可以通過UML提供的擴展用例機制描述類似這樣的場景。 例如對…

大數據學習(95)-謂詞下推

🍋🍋大數據學習🍋🍋 🔥系列專欄: 👑哲學語錄: 用力所能及,改變世界。 💖如果覺得博主的文章還不錯的話,請點贊👍收藏??留言📝支持一…

行式存儲(Row-based Storage)與列式存儲(Column-based Storage)詳細對比

行式存儲(Row-based Storage)與列式存儲(Column-based Storage)詳細對比 1. 數據組織方式 類型行式存儲列式存儲存儲結構按行存儲數據,每條記錄的所有字段(列)連續存放(如一條訂單的…

Seg-Zero:通過認知強化實現的推理鏈引導分割

文章目錄 速覽摘要1. 引言2. 相關工作2.1. 大模型中的推理能力2.2. 結合推理的語義分割2.3. 用于分割任務的 MLLMs 3. 方法3.1. 流程建模(Pipeline Formulation)3.2. Seg-Zero 模型3.3. 獎勵函數(Reward Functions)3.4. 訓練&…

win server2022 限制共享文件夾d

點擊配額管理中的配額 然后創建配額 導入要配額的文件即可 然后確定即可

Docker容器部署Java項目(詳細版)

🤟致敬讀者 🟩感謝閱讀🟦笑口常開🟪生日快樂?早點睡覺 📘博主相關 🟧博主信息🟨博客首頁🟫專欄推薦🟥活動信息 文章目錄 Docker容器部署Java項目1. 環境及準備2. 項目…

C語言深度解析:從零到系統級開發的完整指南

一、C語言的核心特性與優勢 1. 高效性與直接硬件控制 C語言通過編譯為機器碼的特性,成為系統級開發的首選語言。例如,Linux內核通過C語言直接操作內存和硬件寄存器,實現高效進程調度。 關鍵點: malloc/free直接管理內存&#…

Pytorch實現之基于GAN+序列后向選擇的情緒識別增強方法

簡介 簡介:在WGAN-GP+CGAN的基礎上利用了序列后向選擇方法來挑選優質樣本補充到訓練集當中,豐富訓練數據集。 論文題目:基于生成對抗網絡的情緒識別數據增強方法 期刊:傳感技術學報 摘要:使用深度學習方法構建高準確率的情緒識別模型需要大量的情緒腦電數據。 生成對抗…

軟件工程面試題(十九)

1、十六進制的216轉換十進制是多少: 216是16進制,轉10進制: =2*16^2+1*16^1+6*16^0 =512+16+6 =536 2、Java中的XML解析方式: dom和jdom解析 Java中處理XML文檔的標準API有兩種,即XML的簡單API(SAX,Simple API for XML)和文檔對象模型(DOM,…

大模型AI Agent的工作原理與安全挑戰

大模型AI Agent的工作原理與安全挑戰 0x00 引言 智能體(AI Agent)作為大語言模型技術(LLM)的具體應用形式,突破了傳統語言模型僅限于文字輸入與輸出的局限性。其通過感知環境、規劃決策及執行行動的閉環機制&#xf…

膩子刮的遍數越多越好?刮的越厚墻面越平?

很多業主對刮膩子存在誤區,感覺膩子刮的越厚越好,遍數越多越好。同時認為膩子有找平的作用,感覺墻面不平,就是膩子刮的不行。 有一位業主給我留言,說家里的膩子刮了兩遍,然后油工師傅就開始打磨刷漆了&…

「深入解析 Chromium Message Pump:消息循環的核心驅動」

MessagePump 是 Chromium 中 消息循環(Message Loop) 的核心組件之一,負責在不同平臺上管理和分發消息、事件,并協調任務調度。 在瀏覽器這樣的 GUI 應用中,事件循環(Event Loop)是非常重要的&…

3d pose 指標和數據集

目錄 3D姿態估計、3維重建指標: 數據集 EHF數據集 SMPL-X 3D姿態估計、3維重建指標: MVE、PMVE 和 p-MPJPE 都是用于評估3D姿態估計、三維重建等任務中預測結果與真實數據之間誤差的指標。 MVE (Mean Vertex Error):是指模型重建過程中每個頂點的預測位置與真實位置之間…

大智慧大數據面試題及參考答案

目錄 MySQL 的事務隔離級別是什么? MySQL 的覆蓋索引是怎樣的? MySQL 常用的存儲引擎有哪些,它們之間的區別是什么? 在 MySQL 中,如果讀取很大的數據集,同時進行一邊 select 一邊寫入操作,結果會怎樣? 當 ES 出現分詞錯誤的情況時,應該如何處理? Kafka 如何保證…

微服務的簡單認識

目錄 一、微服務架構簡介 二、微服務架構風格和分布式系統架構的關系 三、微服務組成 一、微服務架構簡介 微服務是一種構建分布式系統的架構風格,它將一個大型的應用程序拆分成多個小型的、獨立部署的服務單元,每個服務單元都專注于特定的業務功能,并通過輕量級的通信機…

Spring的 @Conditional @ConditionalOnProperty 注解 筆記250330

Spring的 Conditional ConditionalOnProperty 注解 Spring 的 Conditional 與 ConditionalOnProperty 注解詳解 在 Spring 框架中,Conditional 和 ConditionalOnProperty 是用于動態控制 Bean 注冊的重要注解。雖然它們都服務于條件化配置,但定位和使用…

電路學習——MOS柵極驅動電阻取值(2025.03.30)

參考鏈接1: 驅動芯片的驅動電流的選型和計算 參考鏈接2: NMOS柵極驅動電阻Rg阻值和功率的計算,NMOS柵極驅動電阻Rg的作用,如何防止NMOS誤開通 單片機直接驅動NMOS的方法 RLC諧振電路 智能車BLDC 在此感謝各位前輩大佬的總結,寫這個只是為了記…

mysql JSON_ARRAYAGG聯合JSON_OBJECT使用查詢整合(數組對象)字段

父表數據(表名:class) idname1一年級2二年級3三年級 子表數據(表名:students) idnameclassId11張三112李四113小明3 關聯子表sql查詢(推薦使用方法一) 方法一 (使用IFNull判斷子…

張量-pytroch基礎(2)

張量-pytroch網站-筆記 張量是一種特殊的數據結構,跟數組(array)和矩陣(matrix)非常相似。 張量和 NumPy 中的 ndarray 很像,不過張量可以在 GPU 或其他硬件加速器上運行。 事實上,張量和 Nu…

marked庫(高效將 Markdown 轉換為 HTML 的利器)

文章目錄 前言使用基本使用自定義渲染器例子 代碼高亮 前言 最近嘗試了一下通過星火大模型將ai引入到項目上,但是ai返回的數據可以顯而易見的發現是markedown語法的,那么就需要一個工具,將類似這種的格式轉換為markdown格式 Marked 是一個用…