第三章:GEM分析:gem_object 如何被 GPU 访问(下):gpuva 字段与映射反向索引
先说下要理解本节分析要按如下的的顺序gem_object 如何被 GPU 访问上旧模型 BO-list Relocation 隐式同步旧模型对象每次提交临时定址→ gpuva新模型drm_gpuvm把“对象 → 持久 GPU VA 映射”提取为通用框架→本文回到drm_gem_object自身看它如何持久记录“指向自己的全部映射”。因此本文只分析drm_gem_object自身携带的gpuva字段——它的设计目的、相关 API 与使用方法。至于drm_gpuvm/drm_gpuva框架的整体设计新需求、Split Merge、VM_BIND 流程等见 gpuva。1. 这个字段是什么drm_gem_object里有这样一小块struct{structlist_headlist;// 该对象参与的所有 (对象, VM) 组合链表structmutexlock;// 仅 IMMEDIATE_MODE 下保护 list6.18 引入}gpuva;它的作用只有一个让内核能从一个 GEM 对象出发反向找到这个对象被映射到了哪些 GPU 地址空间、以及每个空间里的哪些具体映射。注意一个极易误解的点gpuva.list挂的不是drm_gpuva而是drm_gpuvm_bo。它是一个两级链表结构见第 3 节。2. 从旧模型接续为什么现在对象需要这条反向链表回顾 gem_object 如何被 GPU 访问上旧模型里“一个gem_object参与了哪些提交、在哪些地址上被访问”是临时的——每次提交靠 BO-list 现场重建提交一结束就不再保留。因此旧模型里对象不需要持久记录“谁在用我”。到了新模型gpuva 的 VM_BIND映射变成持久的用户态预先把对象 bind 到稳定 GPU VA这些drm_gpuva映射会长期存在、跨越多次提交。于是产生一个旧模型没有的新需求——对象必须持久地知道“有哪些映射指向我、分布在哪些 VM”否则驱逐、销毁、校验时无从下手。gpuva字段就是这条持久反向索引它在语义上取代了旧模型里“每次提交临时重建的 BO-list 成员关系”。这条链表的出现本质上是一系列模型转变共同倒逼的结果。把两代模型的关键差异摆在一起看就能明白为什么“反向索引”从可有可无变成了必需维度旧模型BO-list Relocation 隐式同步新模型VM_BIND /drm_gpuvmGPU 地址稳定性早期 relocation 下地址不稳定每次提交可能重定位i915/UMAamdgpu 靠amdgpu_bo_va才有 per-VM 稳定地址用户态显式 bind 到稳定 GPU VA跨多次提交长期不变地址由谁决定内核在提交时隐式决定/修补地址relocation 由内核回填用户态显式分配并控制 VAVM_BIND ioctl映射生命周期临时随单次提交建立、提交结束即失效持久bind 后长期存在与提交解耦同步方式隐式同步内核依据 BO-list 自动串联依赖显式同步用户态用 fence/syncobj 自己表达依赖“谁在用我”如何表达每次提交靠 BO-list现场重建无持久结构靠对象自带的gpuva.list持久记录枚举对象映射的代价无需持久枚举提交上下文里就有完整 BO-list若无反向索引需遍历每个 VM 的整棵区间树 → 故必须内联反向链表控制权归属偏内核托管定址、同步、校验都在内核提交路径偏用户态自管定址、同步显式化内核只维护结构与一致性一句话概括这次演进从“内核隐式处理、地址临时不稳定”走向“用户态显式控制、地址持久稳定”——正是后者让“对象需要持久知道谁在映射自己”成为硬需求gpuva字段应运而生。换个角度看正向问题“某个 VA 映射到谁”由drm_gpuvm的区间树回答见 gpuva 第 3 节反向问题“某个对象参与了哪些映射”就靠本字段的链表。典型的反向操作它们在旧模型里本是每次提交的 BO-list 校验的一部分现在改由持久反向索引驱动对象被驱逐evictBO 从显存被换出后所有指向它的映射都要标记失效、下次使用前重建 PTE。必须能枚举“指向本对象的全部映射”。对象被销毁 / 强制解绑释放前要把它在各个 VM 里的映射全部拆掉。重新校验validate提交前确认对象已回迁并刷新相关映射。如果没有这条反向链表就只能遍历每个 VM 的整棵区间树去找匹配的对象代价高昂。因此框架把反向索引直接内联到 GEM 对象上——这正是gpuva字段存在的理由。它与对象里另一个方向的字段形成对称也正好对应新旧两个阶段对“对象被访问”的不同管理方式字段管的方向回答vma_nodeCPU 侧对象被哪些进程 mmapCPU 地址空间gpuva.listGPU 侧对象被绑定到哪些 GPU 地址空间及其映射对照旧模型旧模型里“GPU 侧”的关系是靠 BO-list 每次提交临时表达的无持久结构新模型把它固化为gpuva.list这条持久链表。3. 两级链表结构gpuva.list的组织是对象 → 每个 VM 一个drm_gpuvm_bo→ 该 VM 内的每条drm_gpuvaVM_2 中该对象的映射VM_1 中该对象的映射第一级: 每个 VM 一个 drm_gpuvm_bolist.entry.gemlist.entry.gemlist.gpuva / gem.entrylist.gpuva / gem.entrydrm_gem_objectgpuva.listdrm_gpuvm_bo (obj, VM_1)drm_gpuvm_bo (obj, VM_2)drm_gpuva [a,r)off0drm_gpuva [b,r)off1drm_gpuva [c,r)off0第一级drm_gem_object.gpuva.list串起若干drm_gpuvm_bo每个代表本对象 × 某个 VM这一唯一组合链接字段是drm_gpuvm_bo.list.entry.gem。第二级每个drm_gpuvm_bo.list.gpuva串起本对象在该 VM 内的全部drm_gpuva链接字段是drm_gpuva.gem.entry。为什么要中间加一层drm_gpuvm_bo而不是让对象直接挂一堆drm_gpuva因为同一对象在同一个 VM里可能有多条映射不同 offset → 不同 VA。用(对象,VM)组合作为聚合点既能按 VM 分组枚举映射又能让 extobj/evicted 等 per-VM 列表复用同一个drm_gpuvm_bo表项。4. 相关 API4.1 启用与初始化API / 标志作用DRIVER_GEM_GPUVAdrm_driver.driver_features驱动声明支持用户自定义 GPU VA 绑定。使用本字段的前提。drm_gem_gpuva_init(obj)初始化gpuva.listINIT_LIST_HEAD。在驱动创建 GEM 对象时调用。staticinlinevoiddrm_gem_gpuva_init(structdrm_gem_object*obj){INIT_LIST_HEAD(obj-gpuva.list);}4.2 遍历宏遍历对象说明drm_gem_for_each_gpuvm_bo(vm_bo, obj)第一级所有drm_gpuvm_bo即对象被绑定的每个 VMdrm_gem_for_each_gpuvm_bo_safe(vm_bo, next, obj)同上可在遍历中删除drm_gpuvm_bo_for_each_va(va, vm_bo)第二级某vm_bo下所有drm_gpuva需持有 GEM 的 gpuva 锁drm_gpuvm_bo_for_each_va_safe(va, next, vm_bo)同上可安全删除嵌套两层即可枚举本对象的全部映射structdrm_gpuvm_bo*vm_bo;structdrm_gpuva*va;drm_gem_for_each_gpuvm_bo(vm_bo,obj)drm_gpuvm_bo_for_each_va(va,vm_bo)do_something(va);// va-vm 是所属 VMva-va.addr/range 是映射区间4.3 锁API作用drm_gem_gpuva_assert_lock_held(gpuvm, obj)lockdep 断言按模式检查持有正确的锁锁规则由 GPUVM 的模式决定默认模式gpuva.list由GEM 的dma_resv锁obj-resv保护。DRM_GPUVM_IMMEDIATE_MODE6.18改由内置的gpuva.lockmutex保护以便在 dma-fence 信号临界路径中修改。在该锁下不得分配内存。断言宏正是据此二选一#definedrm_gem_gpuva_assert_lock_held(gpuvm,obj)\lockdep_assert(drm_gpuvm_immediate_mode(gpuvm)?\lockdep_is_held((obj)-gpuva.lock):\dma_resv_held((obj)-resv))提示头文件里drm_gem_gpuva_init()注释的 “See also drm_gem_gpuva_set_lock()” 是过时引用——早期版本用drm_gem_gpuva_set_lock()设置外部锁现已改为内置gpuva.lockmutex 上述模式判定。4.4 建立/摘除链接跨到框架侧对象侧链表的表项增删由框架侧函数完成这里列出交界处的常用者API作用drm_gpuvm_bo_obtain()/_obtain_locked()/_obtain_prealloc()获取/新建(obj, vm)的drm_gpuvm_bo并挂入对象的gpuva.listdrm_gpuvm_bo_find(vm, obj)查找已存在的drm_gpuvm_bodrm_gpuva_link(va, vm_bo)/drm_gpuva_unlink(va)把一条drm_gpuva挂入/摘出vm_bo即二级链表drm_gpuvm_bo_gem_evict(obj, evict)遍历对象的所有vm_bo批量置驱逐标志5. 使用方法5.1 驱动接入的最小步骤在drm_driver.driver_features里置上DRIVER_GEM_GPUVA。在创建 GEM 对象的路径里调用drm_gem_gpuva_init(obj)。bind 时拿到/新建drm_gpuvm_bodrm_gpuvm_bo_obtain*再对每条映射drm_gpuva_link()unbind 时对应drm_gpuva_unlink()。需要枚举对象映射时驱逐/销毁/校验用 4.2 的两级遍历宏并按 4.3 持好锁。5.2 典型场景 1对象被驱逐时标记全部映射失效/* 持有 obj-resv默认模式或 gpuva.lockimmediate 模式 */voiddriver_bo_evicted(structdrm_gem_object*obj){structdrm_gpuvm_bo*vm_bo;structdrm_gpuva*va;drm_gem_for_each_gpuvm_bo(vm_bo,obj){drm_gem_gpuva_assert_lock_held(vm_bo-vm,obj);/* 该对象在这个 VM 里进入 evicted 列表 */drm_gpuvm_bo_evict(vm_bo,true);/* 逐条映射标记失效下次提交前重建 PTE */drm_gpuvm_bo_for_each_va(va,vm_bo)drm_gpuva_invalidate(va,true);}}上例中drm_gpuvm_bo_gem_evict(obj, true)已封装了遍历 vm_bo 置驱逐标志的部分。5.3 典型场景 2销毁对象前解绑所有映射drm_gem_for_each_gpuvm_bo_safe(vm_bo,next_bo,obj){structdrm_gpuva*va,*next_va;drm_gpuvm_bo_for_each_va_safe(va,next_va,vm_bo){drm_gpuva_unlink(va);// 摘出二级链表drm_gpuva_remove(va);// 从 VM 区间树移除driver_free_pt_and_va(va);// 驱动清理 PTE 与 drm_gpuva 内存}/* vm_bo 的引用释放后会自动摘出对象的 gpuva.list */}6. 小结从演进线看旧模型用临时 BO-list表达“谁在用我”新模型映射持久化后对象改用gpuva字段持久记录这个关系。drm_gem_object.gpuva是对象侧的反向索引从对象快速找到“它参与的所有 GPU 映射”服务于驱逐、销毁、校验等需要按对象枚举映射的场景。它是两级链表对象 →drm_gpuvm_bo每 VM 一个→drm_gpuva每条映射一个。别把gpuva.list当成drm_gpuva的直接列表。用法要点DRIVER_GEM_GPUVAdrm_gem_gpuva_init()初始化drm_gem_for_each_gpuvm_bo()套drm_gpuvm_bo_for_each_va()遍历按模式持obj-resv或gpuva.lock。它与vma_node对称一个记录对象在 CPU 地址空间的映射一个记录在 GPU 地址空间的映射。

相关新闻

企业级AI Agent架构设计与工程实践:以理赔系统为例

企业级AI Agent架构设计与工程实践:以理赔系统为例

在数字化转型浪潮中,企业级 AI Agent(智能体)的应用正从概念走向落地。然而,许多团队在引入 Agent 技术时,常常面临一个典型困境:技术能力在核心部门或少数场景中“扎堆”,却难以有效扩散到整个…

2026/8/13 10:39:13 阅读更多 →
RHEL 9.7系统性能优化实战指南

RHEL 9.7系统性能优化实战指南

1. RHEL 9.7系统优化全景解读 作为企业级Linux发行版的标杆,RHEL 9.7在性能、安全性和稳定性方面都达到了新的高度。但默认安装配置往往无法充分发挥其潜力,特别是在高负载生产环境中。本文将分享我在金融行业核心系统中优化RHEL 9.7的实战经验&#xff…

2026/8/13 10:39:13 阅读更多 →
杭州GEO优化公司怎么选?这份评测把爱搜索、博盈等五家讲透了

杭州GEO优化公司怎么选?这份评测把爱搜索、博盈等五家讲透了

先给结论:在杭州乃至国内GEO优化服务商里,爱搜索、微甜科技、博盈科技排在前三。爱搜索胜在GEO技术全链路自研,微甜科技强在电商广告大盘的承接能力,博盈科技则靠腾讯生态与温州本地化服务站稳一席。这个排序不是简单的名气榜&…

2026/8/13 10:39:13 阅读更多 →

最新新闻

GitHub Actions安全漏洞解析:pull_request_target权限滥用与防御实战

GitHub Actions安全漏洞解析:pull_request_target权限滥用与防御实战

1. 项目概述:当“信任”成为攻击面如果你在团队里负责CI/CD流水线,或者经常在GitHub上维护开源项目,那么“GitHub Actions”和“pull_request_target”这两个词对你来说一定不陌生。前者是GitHub自家的自动化神器,后者则是一个为了…

2026/8/13 11:34:20 阅读更多 →
2026年安徽做智慧燃气安全监管平台的公司有哪些?

2026年安徽做智慧燃气安全监管平台的公司有哪些?

燃气管网平时不起眼,一旦出事就是大事。安徽正处在城镇化快速推进阶段,合肥、芜湖、蚌埠等城市燃气管道里程逐年增长,一批早期铺设的管线陆续进入老化期;皖北平原地势平坦、村镇分布广,皖南山区地形起伏、管线巡护难度…

2026/8/13 11:34:20 阅读更多 →
2026年山西做智慧燃气安全监管平台的公司有哪些?

2026年山西做智慧燃气安全监管平台的公司有哪些?

说到山西,绕不开一个煤字。煤炭、焦化、冶金构成产业支柱的同时,煤层气开发利用起步早、规模大,气源多元的燃气格局让监管链条比一般省份更长。太原盆地城市密集,山区县城散落其间,燃气管线翻山越岭,地形复…

2026/8/13 11:34:20 阅读更多 →
华为机器人仿真工程师面试实录,MuJoCo/场景构建/Sim2Real这些坑别踩

华为机器人仿真工程师面试实录,MuJoCo/场景构建/Sim2Real这些坑别踩

上一篇聊完华为的具身智能大模型工程师,这篇继续聊华为。华为在具身机器人领域的定位跟其他公司不太一样——他们更注重芯片+OS+通信全栈。面试风格也很有特点:系统级思维+基础理论。 MuJoCo:华为为什么重点考这个 华为的机器人仿真工程师面试,MuJoCo几乎是必考项。这跟他…

2026/8/13 11:34:20 阅读更多 →
3分钟快速上手Android虚拟定位:FakeLocation完整使用指南

3分钟快速上手Android虚拟定位:FakeLocation完整使用指南

3分钟快速上手Android虚拟定位:FakeLocation完整使用指南 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 你是否想在保护隐私的同时使用位置相关应用?或者…

2026/8/13 11:34:20 阅读更多 →
AI技能上下文污染:识别、清理与预防全攻略

AI技能上下文污染:识别、清理与预防全攻略

这次我们来看一个在AI应用开发中容易被忽视,但实际影响巨大的问题: AI技能(Skills)的上下文污染 。如果你在使用Claude、GPTs、Cursor、AI Agent或任何基于大语言模型(LLM)的编程助手、聊天机器人时&…

2026/8/13 11:33:20 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者,或者正准备踏入这个领域,那么Visual Studio(后面简称VS)绝对是你绕不开的伙伴。但有时候,这个伙伴会跟你开一个不大不小的玩笑:你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/13 10:41:50 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/13 10:41:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/13 10:41:49 阅读更多 →