02 Xe GPUVM 数据结构与“继承“模型
系列Xe 驱动中drm_gpuvm的实现分析深度定位架构 关键路径。本篇聚焦结构内嵌、类型转换与 flags 复用。1. C 语言里的继承内嵌 container_ofLinux 内核没有 C 的继承机制但通过“把父类结构作为子类的第一个成员”container_of宏可以实现等价效果。drm_gpuvm框架就是围绕这一模式设计的——它的注释里明确写着Typically, this structure is embedded in bigger driver structures.Xe 严格遵循这个约定形成三层平行的父—子结构对核心层父Xe子语义struct drm_gpuvmstruct xe_vm整个 GPU 地址空间struct drm_gpuvastruct xe_vma单个 VA 映射struct drm_gpuva_opstruct xe_vma_op单条 bind 操作内嵌为首成员内嵌为首成员内嵌为首成员xe_vmdrm_gpuvm gpuvmxe_vmadrm_gpuva gpuvaxe_vma_opdrm_gpuva_op basedrm_gpuvmdrm_gpuvadrm_gpuva_op2. 三对结构的内嵌细节2.1xe_vm⊃drm_gpuvmgpuvm是xe_vm的第一个字段见 xe_vm_types.hstructxe_vm{/** gpuvm: base GPUVM used to track VMAs */structdrm_gpuvmgpuvm;/** svm: Shared virtual memory state */struct{structdrm_gpusvmgpusvm;...}svm;...};放在首位不是硬性要求container_of支持任意偏移但放首位可让xe_vm xe_vm.gpuvm转型时偏移为 0也便于阅读。2.2xe_vma⊃drm_gpuva见 xe_vm_types.hstructxe_vma{/** gpuva: Base GPUVA object */structdrm_gpuvagpuva;...u8 tile_mask;// 期望在哪些 tile 建立绑定u8 tile_present;// 哪些 tile 已建立u8 tile_invalidated;// 哪些 tile 的绑定已失效structxe_vma_mem_attrattr;// PAT/atomic/首选内存位置};父结构drm_gpuva提供了所有与硬件无关的字段见 drm_gpuvm.hstructdrm_gpuva{structdrm_gpuvm*vm;// 所属地址空间structdrm_gpuvm_bo*vm_bo;// (VM,BO) 连接点第 5 篇enumdrm_gpuva_flagsflags;// 标志位含用户位见 §4struct{u64 addr;u64 range;}va;// VA 起址 长度struct{u64 offset;structdrm_gem_object*obj;...}gem;// 背后 BOstruct{structrb_nodenode;...}rb;// 区间树节点};2.3xe_vma_op⊃drm_gpuva_op见 xe_vm_types.hstructxe_vma_op{structdrm_gpuva_opbase;// ← 父MAP/REMAP/UNMAP/PREFETCH 通用描述structlist_headlink;// 挂到 xe_vma_ops.listenumxe_vma_op_flagsflags;// COMMITTED / PREV_COMMITTED / NEXT_COMMITTEDu8 tile_mask;union{// 按 op 类型区分的私有数据structxe_vma_op_mapmap;structxe_vma_op_remapremap;structxe_vma_op_prefetchprefetch;structxe_vma_op_map_rangemap_range;...};};base由核心层的 split/merge 算法填充第 6 篇union里的私有字段由 Xe 在解析阶段填充第 7 篇。3. 转型辅助一组container_of内联函数Xe 把所有子←→父转型封装成内联函数集中在 xe_vm.h// gpuvm → xe_vmstaticinlinestructxe_vm*gpuvm_to_vm(structdrm_gpuvm*gpuvm){returncontainer_of(gpuvm,structxe_vm,gpuvm);}// gpuva → xe_vmastaticinlinestructxe_vma*gpuva_to_vma(structdrm_gpuva*gpuva){returncontainer_of(gpuva,structxe_vma,gpuva);}// gpuva → xe_vm跨两层先取 gpuva-vm再转型staticinlinestructxe_vm*gpuva_to_vm(structdrm_gpuva*gpuva){returngpuvm_to_vm(gpuva-vm);}// drm_gpuva_op → xe_vma_opstaticinlinestructxe_vma_op*gpuva_op_to_vma_op(structdrm_gpuva_op*op){returncontainer_of(op,structxe_vma_op,base);}// xe_vma → xe_vm经由内嵌 gpuva 的 vm 指针staticinlinestructxe_vm*xe_vma_vm(structxe_vma*vma){returncontainer_of(vma-gpuva.vm,structxe_vm,gpuvm);}使用场景对照核心层回调把struct drm_gpuvm *传回给 Xe → 用gpuvm_to_vm()拿回xe_vm遍历区间树得到struct drm_gpuva *→ 用gpuva_to_vma()拿回xe_vma遍历 op 列表得到struct drm_gpuva_op *→ 用gpuva_op_to_vma_op()拿回xe_vma_op。这正是第 1 篇提到的双向转型核心层只认父类型Xe 在边界处转回子类型。4. 字段访问器屏蔽父结构布局Xe 没有让代码到处直接写vma-gpuva.va.addr而是包了一层访问器并在文档注释里说明目的是便于将来改实现见 xe_vm.hstaticinlineu64xe_vma_start(structxe_vma*vma){returnvma-gpuva.va.addr;}staticinlineu64xe_vma_size(structxe_vma*vma){returnvma-gpuva.va.range;}staticinlineu64xe_vma_end(structxe_vma*vma){returnxe_vma_start(vma)xe_vma_size(vma);}staticinlineu64xe_vma_bo_offset(structxe_vma*vma){returnvma-gpuva.gem.offset;}staticinlinestructxe_bo*xe_vma_bo(structxe_vma*vma){return!vma-gpuva.gem.obj?NULL:container_of(vma-gpuva.gem.obj,structxe_bo,ttm.base);// 又一次继承转型}注意xe_vma_bo()里再次出现继承模式drm_gem_object内嵌在ttm_buffer_object里ttm_buffer_object又内嵌在xe_bo里于是gem.obj → xe_bo也靠container_of。5. flags 复用把驱动私有状态塞进DRM_GPUVA_USERBITS这是 Xe 用drm_gpuvm的一处巧思。核心层在drm_gpuva.flags里只定义了 3 个位见 drm_gpuvm.henumdrm_gpuva_flags{DRM_GPUVA_INVALIDATED(10),// 背后 BO 已失效DRM_GPUVA_SPARSE(11),// 稀疏映射NULL 映射DRM_GPUVA_USERBITS(12),// ← 用户可用位起点};从DRM_GPUVA_USERBITSbit 2往上全部留给驱动。Xe 就在这里定义了 11 个私有标志见 xe_vm_types.h#defineXE_VMA_READ_ONLYDRM_GPUVA_USERBITS// bit 2 只读#defineXE_VMA_DESTROYED(DRM_GPUVA_USERBITS1)// bit 3 已销毁#defineXE_VMA_ATOMIC_PTE_BIT(DRM_GPUVA_USERBITS2)// bit 4 原子 PTE#defineXE_VMA_PTE_4K(DRM_GPUVA_USERBITS3)// bit 5 ┐#defineXE_VMA_PTE_2M(DRM_GPUVA_USERBITS4)// bit 6 ├ 当前 PTE 页尺寸#defineXE_VMA_PTE_1G(DRM_GPUVA_USERBITS5)// bit 7 │#defineXE_VMA_PTE_64K(DRM_GPUVA_USERBITS6)// bit 8 ┘#defineXE_VMA_PTE_COMPACT(DRM_GPUVA_USERBITS7)// bit 9 紧凑 PTE#defineXE_VMA_DUMPABLE(DRM_GPUVA_USERBITS8)// bit 10 可被 coredump#defineXE_VMA_SYSTEM_ALLOCATOR(DRM_GPUVA_USERBITS9)// bit 11 CPU 地址镜像/SVM#defineXE_VMA_MADV_AUTORESET(DRM_GPUVA_USERBITS10)// bit 12 madvise 自动复位好处这些状态与每个 VMA 一一对应直接复用父结构已有的flags字段无需在xe_vma里额外加成员省内存也省一次间接访问。对应的判定函数直接读 flags见 xe_vm.hstaticinlineboolxe_vma_read_only(structxe_vma*vma){returnvma-gpuva.flagsXE_VMA_READ_ONLY;}staticinlineboolxe_vma_is_null(structxe_vma*vma){returnvma-gpuva.flagsDRM_GPUVA_SPARSE;}// 直接复用核心层的 SPARSE 位staticinlineboolxe_vma_is_cpu_addr_mirror(structxe_vma*vma){returnvma-gpuva.flagsXE_VMA_SYSTEM_ALLOCATOR;}注意xe_vma_is_null()复用的是核心层的DRM_GPUVA_SPARSE而is_cpu_addr_mirror()用的是驱动私有的XE_VMA_SYSTEM_ALLOCATOR——一个映射的语义由核心位 用户位共同决定。6. VMA 的三种形态与再一层继承userptr通过组合上述 flagsXe 的xe_vma有四种互斥形态判定逻辑见 xe_vm.h形态判定背后存储BO 映射gem.obj ! NULL一个xe_boNULL / sparseDRM_GPUVA_SPARSE无读 0 写弃CPU 地址镜像XE_VMA_SYSTEM_ALLOCATORSVM 按需缺页userptr无 BO 且非 null 非镜像用户进程内存页staticinlineboolxe_vma_is_userptr(structxe_vma*vma){returnxe_vma_has_no_bo(vma)!xe_vma_is_null(vma)!xe_vma_is_cpu_addr_mirror(vma);}其中userptr又引入第二层继承——它在xe_vma之外再包一层xe_userptr_vma见 xe_vm_types.h 和 xe_vm.hstructxe_userptr_vma{structxe_vmavma;// ← 父structxe_userptruserptr;// 额外的 userptr 状态mmu notifier 等};staticinlinestructxe_userptr_vma*to_userptr_vma(structxe_vma*vma){xe_assert(xe_vma_vm(vma)-xe,xe_vma_is_userptr(vma));returncontainer_of(vma,structxe_userptr_vma,vma);// 又一次 container_of}于是形成一条三级继承链drm_gpuvaxe_vmadrm_gpuva gpuvaxe_userptr_vmaxe_vma vma\nxe_userptr userptr调用to_userptr_vma()前必须先用xe_vma_is_userptr()确认形态函数里有xe_assert兜底否则container_of会得到非法指针。7. 本篇小结机制作用代表符号结构内嵌首成员让 Xe 类型是一个 DRM 核心类型xe_vm.gpuvm/xe_vma.gpuvacontainer_of转型在核心层回调边界还原子类型gpuvm_to_vm/gpuva_to_vma/gpuva_op_to_vma_op字段访问器屏蔽父结构布局便于演进xe_vma_start/size/end/boUSERBITS复用私有 VMA 状态零额外内存XE_VMA_READ_ONLY…XE_VMA_SYSTEM_ALLOCATOR多级继承userptr 在 vma 上再扩展xe_userptr_vma/to_userptr_vma理解了这套继承 转型 flags 复用的骨架后续所有回调和 bind 流程读起来都会顺畅——每当核心层给你一个drm_*指针你就知道该用哪个container_of把它变回xe_*。关键源码位置速查主题文件关键符号三对结构定义drivers/gpu/drm/xe/xe_vm_types.hxe_vm/xe_vma/xe_vma_op转型 访问器drivers/gpu/drm/xe/xe_vm.hgpuva_to_vma/xe_vma_start…父结构定义include/drm/drm_gpuvm.hdrm_gpuva/drm_gpuva_flags私有 flagsdrivers/gpu/drm/xe/xe_vm_types.hXE_VMA_*L41–L52userptr 子类drivers/gpu/drm/xe/xe_vm_types.hxe_userptr_vma下一篇第 3 篇《VM 的创建与销毁》——xe_vm_create()如何一步步调用drm_gpuvm_init()DRM_GPUVM_RESV_PROTECTED与共享 resv 对象的意义根页表 / scratch page 的建立以及引用计数归零后vm_free回调与异步销毁 worker 的配合。

相关新闻

手把手教你掌握新一代AI工具(线上版)

手把手教你掌握新一代AI工具(线上版)

新手必看:手把手教你掌握新一代 AI 工具,快速提升生产力///“虾仔”>>>:jzit点top 在 2026 年的今天,AI 早已褪去“科技噱头”的标签,化作无数普通人桌面上的生产力引擎。然而,面对海量的 AI 产品…

2026/10/17 11:57:43 阅读更多 →
不要先问“用哪个 AI”,先盘点你的开发工作流

不要先问“用哪个 AI”,先盘点你的开发工作流

文章目录开篇本文不会讨论什么一、为什么不要一开始就问“用哪个 AI”二、一条完整开发工作流,通常包含哪些环节三、盘点工作流时,重点看这 5 个节点1. 需求到任务:你是不是经常边写边猜2. 阅读代码:你是不是总在找“入口到底在哪…

2026/10/17 11:57:09 阅读更多 →
Dism++系统优化指南:免费清理Windows垃圾的终极实战手册,三步腾出10GB磁盘空间

Dism++系统优化指南:免费清理Windows垃圾的终极实战手册,三步腾出10GB磁盘空间

Dism系统优化指南:免费清理Windows垃圾的终极实战手册,三步腾出10GB磁盘空间 【免费下载链接】Dism-Multi-language Dism Multi-language Support & BUG Report 项目地址: https://gitcode.com/gh_mirrors/di/Dism-Multi-language 周五晚&…

2026/10/17 12:56:22 阅读更多 →

最新新闻

Unity WebGL跨平台自动全屏横屏适配方案:Windows、安卓、iOS全兼容

Unity WebGL跨平台自动全屏横屏适配方案:Windows、安卓、iOS全兼容

简介:这份资源是面向Unity开发者的WebGL多平台适配Demo,重点解决Unity WebGL打包后在Windows浏览器、Android与iOS移动设备上自动全屏并强制横屏显示的问题。内容围绕Screen.fullScreen与Screen.orientation的调用、Application.platform平台检测、WebGL…

2026/10/18 13:12:50 阅读更多 →
xAI推出Grok Bot智能体平台:用Cursor Base URL改到TaoToken实测自主任务流

xAI推出Grok Bot智能体平台:用Cursor Base URL改到TaoToken实测自主任务流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:12:50 阅读更多 →
【Lora分享】国产可图大模型厚积薄发,GLM3加持质的飞跃,ComfyUI最全指南与SD3综合评比孰更强?TaoToken统一Key实战

【Lora分享】国产可图大模型厚积薄发,GLM3加持质的飞跃,ComfyUI最全指南与SD3综合评比孰更强?TaoToken统一Key实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:12:50 阅读更多 →
OpenClaw Linux 完整安装指南:从环境准备到 TaoToken 统一 Key 接入

OpenClaw Linux 完整安装指南:从环境准备到 TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:12:50 阅读更多 →
AI辅助工具调研:把 Cline MCP 的 endpoint 改到 TaoToken 的配置记录

AI辅助工具调研:把 Cline MCP 的 endpoint 改到 TaoToken 的配置记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:12:50 阅读更多 →
pH敏感型IgG标记试剂:从抗体标记设计到活细胞内吞追踪的实战指南

pH敏感型IgG标记试剂:从抗体标记设计到活细胞内吞追踪的实战指南

做这行做久了会发现,抗体标记这件事,看着是"把荧光染料接到IgG上"这么一步操作,真正拉开差距的,全在细节里。普通标记试剂只能告诉你抗体在哪里,而pH敏感型IgG标记试剂能告诉你抗体到了什么环境、经历了什么…

2026/10/18 13:11:50 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →