尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

第八章:命令提交: 8.1 命令提交总览:从 CS ioctl 到 fence 返回

第八章:命令提交: 8.1 命令提交总览:从 CS ioctl 到 fence 返回 前面各章已分别剖析了命令提交所涉及的各个核心组件——GEM 对象是显存的载体、TTM负责将其放置到目标内存域、dma-fence 描述何时完成、dma_resv 记录谁在使用、GPU Scheduler 决定其提交至硬件 ring 的时机至于维护 GPU 地址空间视图的 GPUVM则留待下一章第九章专门展开。命令提交正是将上述组件在一次系统调用中完成组装、最终驱动 GPU 执行的主干路径——它既是前述各章机制的汇聚点也引出下一章的 GPUVM。本章以 AMDGPUGFX 引擎的实现为示例进行剖析但所述原理与主流程同样适用于 Intel、ARM Mali、高通 Adreno 乃至国产 GPU 的驱动——命令提交是 DRM 框架的通用范式各家实现差异仅在于引擎细节整体架构则完全一致。需要指出的是当前提交范式正处于演进之中一是以每次提交携带 BO 列表、由内核逐次校验并中介的传统提交模式即本章所述amdgpu_cs_ioctl路径二是以VM_BIND预先建立常驻映射、全面依赖显式同步、由用户态直接向硬件队列提交的新型提交模式Xe 与 amdgpu user queue 已采用将在第九章 GPUVM 一并展开。本章聚焦传统提交模式——它在图形渲染领域已成为统一标准也是理解新型模式演进动因的基础而 AI 计算负载则正逐步转向 user queue 直提模式。1. 整体模型概述用户态提交一次绘制或计算其本质是向内核传递三类信息使用哪些 BObuffer list——内核需将其锁定、验证驻留状态并建立 GPU 映射执行哪些命令IBIndirect Buffer——承载 GPU 指令的显存缓冲区依赖关系in-fence / out-fence——本次提交依赖哪些操作、又被哪些操作依赖以保证跨引擎、跨进程的执行顺序。内核处理完成后仅向用户态返回一项结果一个序列号seq其背后对应一个dma_fence即本次提交完成时将被 signal 的凭证。提交为异步操作ioctl 返回并不代表 GPU 执行完毕仅表示作业已入队、fence 已就绪。用户态后续可凭该 seq 通过amdgpu_cs_wait_ioctl阻塞等待完成或经amdgpu_cs_fence_to_handle_ioctl将其导出为 syncobj / sync_file 以便跨进程、跨 API 传递——由此构成“提交即返回、完成靠 fence”的异步闭环。立即返回 seq/fence完成时 signal fence用户态drmCommandWrite(DRM_AMDGPU_CS)内核 amdgpu_cs_ioctldrm_sched 队列GPU ring2. 命令提交在全书中的定位机制汇聚点之所以将命令提交置于调度、GPUVM 之后单独成章在于它是前述所有机制的汇聚点。下表将本次提交的每个阶段对应至前文相应章节提交阶段依赖的机制对应章节锁定并验证 BOdrm_execttm_bo_validatedma_resv第四章 TTM、6.3 dma_resv更新 GPU 页表amdgpu_vm_*/ GPUVM第九章 GPUVM收集依赖 fencedma-fence / syncobj / dma_resv第六章 同步构建并入队作业drm_sched_job第七章 GPU Scheduler回写完成 fencedma_resv_add_fence6.3 dma_resv简言之理解命令提交即可将第四章至第九章的机制串联为一条完整闭环。3. amdgpu_cs_ioctl 九步全景现代 amdgpu6.8将 CS 划分为九个明确的阶段amdgpu_cs_ioctl()依次调用drm_schedGPUVMdrm_exec (BO 锁)amdgpu_cs_ioctl用户态drm_schedGPUVMdrm_exec (BO 锁)amdgpu_cs_ioctl用户态DRM_AMDGPU_CS (chunks)1① parser_init 解析 chunks/取 ctx/bo_list2② pass1 统计 IB/userptr分配 job3③ pass2 填充 IB 描述4④ parser_bos drm_exec 预留锁定所有 BO5validate 回迁 收集 userptr HMM range6⑤ patch_jobs patch IB 地址等7⑥ vm_handling clear_freed / bo_update / update_pdes8⑦ sync_rings 收集显式隐式依赖 fence 进 job9⑧ submit arm→回写 dma_resv→push_job→返回 seq10⑨ parser_fini 释放解析上下文11cs-out.handle seq12逐步说明#函数关键动作①amdgpu_cs_parser_init从用户态拷入 chunk 数组取出amdgpu_ctx调度上下文与amdgpu_bo_list本次提交涉及的 BO 清单②amdgpu_cs_pass1第一遍扫描 chunks统计 IB 数量、识别 userptr按 gang 分配amdgpu_job③amdgpu_cs_pass2第二遍扫描将每个 IB chunk 的地址与大小写入 job处理依赖 / syncobj chunk④amdgpu_cs_parser_bos使用drm_exec一次性预留并加锁所有相关 BObo_list 隐式导入的共享 BO对已被驱逐的 BO 调用ttm_bo_validate回迁对 userptr 建立 HMM range⑤amdgpu_cs_patch_jobs对 IB 执行必要的地址修补⑥amdgpu_cs_vm_handlingGPUVM 处理amdgpu_vm_clear_freed清理已解除的映射、amdgpu_vm_bo_update刷新 BO 映射、amdgpu_vm_update_pdes更新页目录并将页表更新 fence 收入p-sync作为依赖⑦amdgpu_cs_sync_rings将显式依赖in-fence / syncobj与隐式依赖从 BO 的dma_resv读取的 fence统一收集为 job 的依赖⑧amdgpu_cs_submit见下节详解——arm、回写 fence、push job、返回 seq⑨amdgpu_cs_parser_fini释放 chunks、sync、drm_exec、ctx、bo_list 等解析期资源任一阶段失败均会跳转至error_fini/error_backoff执行回滚已持有的锁经由drm_exec统一 backoff已分配的 job 被释放确保不残留半提交状态。4. 第八阶段 submit 的临界区fence 的落地过程amdgpu_cs_submit()是整个提交流程的临界收尾阶段其逻辑需单独剖析是否drm_sched_job_arm 每个 job生成 scheduled/finished 双 fencegang 内部非 leader 的 scheduled加为 leader 的依赖持 notifier_lock禁止内存分配userptr 是否失效或有 BO 仍在 moved返回 -EAGAINlibdrm 重试整个 ioctl遍历每个锁定 BOdma_resv_add_fence 回写leaderWRITE其余READamdgpu_ctx_add_fence 取 seqdrm_sched_entity_push_job正式入队cs-out.handle seq解锁返回三个关键点双 fence 语义drm_sched_job_arm()为每个 job 生成scheduled与finished两枚 fence详见 7.5。返回给用户态的 seq 对应的是 leader 的finished。fence 回写dma_resv提交成功后将本次的 finished fence 按用途写者DMA_RESV_USAGE_WRITE、读者DMA_RESV_USAGE_READ挂载到每个 BO 的dma_resv上——这正是隐式同步得以成立的关键步骤后续其他提交使用同一 BO 时即可从dma_resv读取该 fence 并据此等待。userptr / HMM 的最终校验在notifier_lock保护下复核 userptr range 是否在parser_bos之后被mmu_notifier判定为失效若失效则返回-EAGAINlibdrm 将透明重试整个 ioctl与第九章 SVM 的缺页 / 失效处理同源。5. 显式同步与隐式同步的汇聚命令提交是两种同步策略见 6.2的实际落地环节隐式同步显式同步依赖来源BO 的dma_resv内核自动读取用户态传入的 in-fence / syncobj chunk收集时机⑦sync_rings从锁定 BO 的 resv 读取②③ 解析 chunk ⑦ 汇总完成回写⑧dma_resv_add_fence自动挂载out-fence / post-dep syncobj 由用户态领取一次提交可同时携带隐式与显式依赖内核将其统一纳入drm_sched_job的依赖集合由调度器在作业提交至硬件 ring 前逐一等待。6. 与旧模型的关系3.2.3 介绍过早期的BO-list Relocation 隐式同步模型。现代路径的差异在于Relocation 基本淘汰用户态改用固定 VA配合 GPUVM 的VM_BIND类语义IB 中直接写入最终 GPU 地址内核不再逐条重定位显式同步成为一等公民syncobj / timeline 使跨进程、跨 APIVulkan编排成为常态drm_exec取代手写 ticket 循环统一的加锁 / 回退框架消除了死锁风险与重试样板代码。因此在阅读顺序上建议将 3.2.3 视为历史背景本章视为现代主线。7. 小结命令提交 锁定 BO → 建立映射 → 收集依赖 → 入队 → 回写 fence五阶段闭环它将第四至第九章的机制汇聚于一次 ioctl是理解 BO 生命周期最活跃阶段的枢纽返回用户态的仅为 seq/fence提交为异步操作完成状态由 fence 表征amdgpu 通过amdgpu_cs_ioctl的九个阶段实现了该主干流程其中parser_bos加锁验证与submit回写 fence 入队是两个最关键的节点。下一节 8.2 将深入前端解析阶段第 ①②③ 步专门阐述 chunk 解析、IB 提取与amdgpu_job分配如何把用户态请求翻译为可调度的作业随后 8.3 再聚焦第 ④ 阶段阐述drm_execttm_bo_validatedma_resv如何协同完成锁定与验证。
返回列表