Windows 图形显示驱动开发-WDDM 3.2-用户模式工作提交(二)

news/2025/3/10 21:45:47/
用户模式工作提交 API

添加了以下用户模式 API,以支持用户模式工作提交。

  • D3DKMTCreateDoorbell 为 D3D HWQueue 创建一个Ring,用于用户模式工作提交。
  • D3DKMTConnectDoorbell 将先前创建的Ring连接到 D3D HWQueue,用于用户模式工作提交。
  • D3DKMTDestroyDoorbell 销毁先前创建的Ring。
  • D3DKMTNotifyWorkSubmission 通知 KMD 在 HWQueue 上提交了新工作。 此功能的重点是一个低延迟的工作提交路径,其中 KMD 不参与或不知道何时提交工作。 当在 HWQueue 上提交工作时需要通知 KMD 的情况下,此 API 非常有用。 驱动程序应在特定且不常见的方案中使用此机制,因为它涉及到每次提交工作时从 UMD 到 KMD 的往返,从而违背了低延迟用户模式提交模型的目的。
Ring内存和环形缓冲区分配的驻留模型

UMD 负责在创建Ring之前使环形缓冲区和环形缓冲区控制分配驻留。

  • UMD 管理环形缓冲区的生命周期和环形缓冲区控制分配。 即使相应的Ring被销毁,Dxgkrnl 也不会隐式地销毁这些分配。 UMD 负责分配和销毁这些分配。 但是,为了防止恶意用户模式程序在Ring处于活动状态时销毁这些分配,Dxgkrnl 确实会在Ring的生命周期内对这些分配进行引用。
  • Dxgkrnl 销毁环形缓冲区分配的唯一方案是在设备终止期间。 Dxgkrnl 销毁与设备关联的所有 HWQueue、Ring和环形缓冲区分配。
  • 只要环形缓冲区分配处于活动状态,环形缓冲区 CPUVA 始终有效,并且可供 UMD 访问,而与Ring连接状态无关。 也就是说,环形缓冲区驻留与Ring无关。
  • 当 KMD 进行 DXG 回调以断开Ring时(即,调用状态为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_RETRY 的 DxgkCbDisconnectDoorbell),Dxgkrnl 将Ring CPUVA 旋转到一个虚拟页面。 它不会收回或取消映射环形缓冲区分配。
  • 在任何设备丢失的情况下(TDR/GPU 停止/分页等),Dxgkrnl 会断开Ring并将状态标记为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_ABORT。 用户模式负责销毁 HWQueue、Ring、环形缓冲区并重新创建它们。 此要求类似于在此方案中销毁和重新创建其他设备资源的方式。
硬件上下文挂起

当 OS 挂起硬件上下文时,Dxgkrnl 会保持Ring连接处于活动状态,并常驻环形缓冲区(工作队列)分配。 通过这种方式,UMD 可以继续排队工作到上下文;当上下文被挂起时,这项工作不会被安排。 一旦上下文被恢复和计划,GPU 的上下文管理处理器 (CMP) 就会观察新的写入指针和工作提交。

此逻辑类似于当前的内核模式提交逻辑,其中 UMD 可以使用挂起的上下文调用 D3DKMTSubmitCommand。 Dxgkrnl 将这个新命令排队到 HwQueue,但直到以后才能被安排。在硬件上下文挂起和恢复期间,会发生以下事件序列。

挂起硬件上下文:

Dxgkrnl 调用 DxgkddiSuspendContext。

KMD 从 HW 计划程序列表中删除上下文的所有 HWQueue。
Ring仍处于连接状态,环形缓冲区/环形缓冲区控制分配仍处于驻留状态。 UMD 可以将新命令写入此上下文的 HWQueue,但 GPU 不会处理它们,这类似于当前内核模式命令提交到挂起的上下文。

如果 KMD 选择破坏挂起的 HWQueue 的Ring,则 UMD 将断开其连接。 UMD 可以尝试重新连接Ring,KMD 将为该队列分配一个新的Ring。 其目的不是使 UMD 停滞,而是允许它继续提交工作;一旦上下文恢复,HW 引擎最终可以处理这些工作。

恢复硬件上下文:
Dxgkrnl 调用 DxgkddiResumeContext。
KMD 将上下文的所有 HWQueue 添加到 HW 计划程序的列表。

引擎 F 状态转换

在传统的内核模式工作提交中,Dxgkrnl 负责向 HWQueue 提交新命令,并监视来自 KMD 的完成中断。 因此,Dxgkrnl 可以完整地了解引擎何时处于活动状态和空闲状态。

在用户模式工作提交中,Dxgkrnl 使用 TDR 超时节奏监视 GPU 引擎是否正在进行。因此,如果值得在两秒的 TDR 超时时间之前启动到 F1 状态的转换,KMD 可以请求 OS 执行此操作。

为了促进这一做法,作出了以下改动:

DXGK_INTERRUPT_GPU_ENGINE_STATE_CHANGE 中断类型被添加到 DXGK_INTERRUPT_TYPE。 KMD 使用此中断通知 Dxgkrnl 引擎状态转换,这些转换需要 GPU 电源操作或超时恢复,例如 Active -> TransitionToF1 和 Active -> Hung。

EngineStateChange 中断数据结构被添加到 DXGKARGCB_NOTIFY_INTERRUPT_DATA。
添加了 DXGK_ENGINE_STATE 枚举来表示 EngineStateChange 的引擎状态转换。
当 KMD 引发 DXGK_INTERRUPT_GPU_ENGINE_STATE_CHANGE 中断时,EngineStateChange.NewState 设置为 DXGK_ENGINE_STATE_TRANSITION_TO_F1,Dxgkrnl 会断开此引擎上 HWQueue 的所有Ring的连接,然后启动 F0 到 F1 电源组件转换。

当 UMD 试图在 F1 状态下向 GPU 引擎提交新工作时,需要重新连接Ring,这反过来又会导致 Dxgkrnl 启动转换回 F0 电源状态。

引擎 D 状态转换

在 D0 到 D3 设备电源状态转换期间,Dxgkrnl 挂起 HWQueue,断开Ring(将Ring CPUVA 旋转到虚拟页面),并将 DoorbellStatusCpuVirtualAddress Ring状态更新为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_RETRY。

如果 UMD 在 GPU 处于 D3 时调用 D3DKMTConnectDoorbell,则会强制 Dxgkrnl 将 GPU 唤醒到 D0。 Dxgkrnl 还负责恢复 HWQueue,并将Ring CPUVA 旋转到物理Ring位置。

事件发生的顺序如下。

  • 发生 D0 到 D3 GPU 断电:
  • 对于 GPU 上的所有 HW 上下文,Dxgkrnl 调用 DxgkddiSuspendContext。 KMD 从 HW 计划程序列表中删除这些上下文。
  • Dxgkrnl 断开所有Ring的连接。
  • 如有必要,Dxgkrnl 可能会从 VRAM 中逐出所有环形缓冲区/环形缓冲区控制分配。 一旦所有上下文都被挂起并从硬件计划程序的列表中删除,硬件就不会引用任何被逐出的内存。
  • 当 GPU 处于 D3 状态时,UMD 会将新命令写入 HWQueue:
  • UMD 看到Ring已断开连接,因此调用 D3DKMTConnectDoorbell。
  • Dxgkrnl 启动 D0 转换。
  • Dxgkrnl 使所有环形缓冲区/环形缓冲区控制分配都驻留(如果它们被逐出)。
  • Dxgkrnl 调用 KMD 的 DxgkddiCreateDoorbell 函数,以请求 KMD 为此 HWQueue 建立Ring连接。
  • Dxgkrnl 为所有 HWContext 调用 DxgkddiResumeContext。 KMD 将相应的队列添加到 HW 计划程序列表。

http://www.ppmy.cn/news/1578181.html

相关文章

小米安全攻防工程师面试题解析

前言: 本文将分享一些小米安全攻防工程师面试中的经典题目和答案解析,帮助大家更好地准备面试。以下内容涵盖了SQL注入、PHP与Java的预编译区别、SSRF攻击、防御方法等。 1. SQL注入怎么预防,预编译为什么能防? SQL注入是攻击者…

系统架构设计师—数据库基础篇—数据库优化技术

文章目录 集中式数据库反规范化设计分类保证数据的一致性方法 分布式数据库主从复制基本过程binlog的同步模式MySQL的同步模式 读写分离分表分库 分布式缓存技术-Redis数据类型读写数据的基本步骤读数据写数据 过期策略惰性删除定期删除内存淘汰机制 持久化缓存异常问题缓存穿透…

小程序 -- uni-app开发微信小程序环境搭建(HBuilder X+微信开发者工具)

目录 前言 一 软件部分 1. 微信开发者工具 2. HBuilder X 开发工具 二 配置部分 1. 关于 HBuilder X 配置 2. 关于 微信开发工具 配置 三 运行项目 1. 新建项目 2. 代码编写 3. 内置浏览器 编译 4. 配置小程序 AppID获取 注意 四 实现效果 前言 uni-app开发小程…

K8s 1.27.1 实战系列(六)Pod

一、Pod介绍 1、Pod 的定义与核心设计 Pod 是 Kubernetes 的最小调度单元,由一个或多个容器组成,这些容器共享网络、存储、进程命名空间等资源,形成紧密协作的应用单元。Pod 的设计灵感来源于“豌豆荚”模型,容器如同豆子,共享同一环境但保持隔离性。其核心设计目标包括…

【2025深夜随笔】简单认识一下Android Studio

【2025深夜随笔】Android Studio 全生命周期开发指南:从安装到项目实战简单解析 一、Android Studio 核心认知 1.1 官方定位与生态价值 Android Studio(简称AS)是谷歌官方推出的 安卓开发IDE(集成开发环境)&#xff…

计算机网络笔记(二)——1.2互联网概述

1.2.1网络的网络 起源于美国的互联网现已发展成为世界上最大的覆盖全球的计算机网络。 下面,我们先来看看关于网络、互连网、互联网(因特网)的一些基本概念。为了方便,后面我们所称呼的"网络"往往就是"计算机网络",而不是电信网或有…

【0基础学Python】基础语法Part1

第一个python程序 print(12-3) print(hello world!) print(12/3)熟悉 C / Java 的同学可能认为, 2 / 3 结果为 0 (小数部分被截断). 但是在 Python 中得到的结果则是 一个小数. 更符合日常使用的直觉。 变量和类型 python无需声明变量类型,会自动确定你所写的变量…

NO.25十六届蓝桥杯备战|字符数组|初始化|输入|输出|strlen|gets|fgets|strcpy|strcat(C++)

字符数组 字符数组介绍 数组的元素如果是字符类型,这种数组就是字符数组,字符数组可以是⼀维数组,可以是⼆维数组(多维数组)。 接下来主要讨论⼀维的字符数组。 char arr1[5]; //⼀维数组 char arr2[3][5];//⼆维…