ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

第二章:DRM 框架概述:2.1.3 drm_file — 客户端上下文

第二章:DRM 框架概述:2.1.3 drm_file — 客户端上下文 2.1 DRM 框架核心对象速览确立了三个对象的关系。三者之中drm_file是BO 主线里出现频率最高的关联对象后续每一章几乎都要触碰它的某个字段。每次用户态open(/dev/dri/renderD128)都会创建一个drm_file实例它封装「某个进程对这块 GPU 的一次打开」的全部 per-client 状态——handle 表、syncobj 表、PRIME 导入缓存、以及驱动私有的 GPU 地址空间。1. 定位一次 open 就是一个隔离的客户端drm_file的粒度是「每次 open 一份」——同一进程 open 两次会得到两个独立的drm_file不同进程之间更是彼此隔离。它承载的所有资源都是per-file的进程 A 的 GEM handle 42 与进程 B 的 handle 42 指向不同对象A 的 GPU 虚拟地址空间与 B 完全独立。这条「per-file 隔离」是理解后续 GEM handle、syncobj、GPUVM 语义的总前提。2. 与 BO 主线直接相关的字段字段含义后续章节使用场景object_idrGEM handle →drm_gem_object *的映射表Ch3drm_gem_handle_create()插入、GEM_CLOSE删除syncobj_idrsyncobj handle →drm_syncobj *的映射表Ch6drm_syncobj_create()/SYNCOBJ_WAITprimePRIME 导入缓存dma-buf → handleCh5避免同一个 dma-buf 重复导入生成多个 handledriver_priv驱动私有指针amdgpu 在此存放amdgpu_fpriv含 ctx_mgr→Ch7、CS→Ch8、VM→Ch9pid/client_id进程标识调试clientsdebugfs、fdinfominor打开的设备节点file-minor-dev反查drm_device区分 primary/render/accel 权限authenticated是否已认证render node 自动认证primary 需要 master 授权object_idr、syncobj_idr、driver_priv是 BO 主线反复出现的三个字段其中driver_priv承载了驱动扩展的全部 per-client 状态下面以 amdgpu 为例展开。3. amdgpu 的 drm_file 扩展amdgpu_fprivDRM 核心把 per-driver 的客户端状态统一交给driver_priv。amdgpu 在 open 时分配一个amdgpu_fpriv挂上去// drivers/gpu/drm/amd/amdgpu/amdgpu.hstructamdgpu_fpriv{structamdgpu_vmvm;// per-client GPU 虚拟地址空间 → Ch9structamdgpu_bo_va*prt_va;// PRT(Partially Resident Textures)structmutexbo_list_lock;structidrbo_list_handles;// CS 提交时的 BO 列表 → Ch8structamdgpu_ctx_mgrctx_mgr;// 上下文管理 → Ch7 scheduler entitystructamdgpu_eviction_fence_mgrevf_mgr;// eviction fence};关键洞察在 amdgpu 中每次open()都会创建独立的amdgpu_vmGPU 页表空间这意味着不同进程有隔离的 GPU 地址空间。这是理解 Ch9 GPUVM 的前提也是「per-file 隔离」在驱动层的直接体现。4. drm_file 的生命周期drm_file的创建与销毁分别挂在open()/close()两端DRM 核心负责通用部分驱动通过drm_driver.open/postclose回调见 2.1.1对称地建立与拆除私有资源open(/dev/dri/renderD128) → drm_open() → drm_file_alloc() // 分配 drm_file初始化 idr 表 → drm_driver.open() // 驱动回调amdgpu_driver_open_kms() → 分配 amdgpu_fpriv → 创建 amdgpu_vmGPU 页表 → 初始化 ctx_mgr ... 用户操作create BO / submit job / ...... close(fd) → drm_release() → drm_file_free() → 遍历 object_idr释放所有 GEM handle减引用 → 遍历 syncobj_idr释放所有 syncobj → drm_driver.postclose() // 驱动回调 → 销毁 amdgpu_vm → 销毁 ctx_mgrflush 所有 entity → kfree(amdgpu_fpriv)close 路径的「对称拆除」保证了进程退出即回收全部 per-client 资源handle 减引用、syncobj 释放、GPU 映射拆除、entity flush无需用户显式清理。5. 与后续章节的关系概览Ch3 GEMhandle 是 per-file 的——进程 A 的 handle 42 和进程 B 的 handle 42 指向不同对象。Ch5 共享PRIME fd 是跨进程的但导入后生成的 handle 仍是 per-file 的prime缓存去重。Ch6 显式同步syncobj 也挂在syncobj_idr与 GEM handle 同为 per-file 句柄。Ch7 Schedulerentity 通常在amdgpu_ctx属于ctx_mgr中创建随 file close 一起销毁。Ch8 命令提交bo_list_handles记录 CS 提交时的 BO 列表。Ch9 GPUVMamdgpu_vm是 per-file 的file close 时所有 GPU 映射被拆除。6. 小结drm_file是「一次 open」的客户端上下文粒度为 per-file所有资源彼此隔离。object_idr/syncobj_idr是 per-file 句柄表driver_priv承载驱动扩展amdgpu 为amdgpu_fpriv。生命周期由open/postclose回调对称管理进程退出即回收全部 per-client 资源。后续每一章几乎都会触碰它的某个字段——这是本专栏最值得优先精读的框架对象。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进