当前位置:首页>Linux>Linux HMM 共享虚拟内存SVM 架构及工作原理

Linux HMM 共享虚拟内存SVM 架构及工作原理

  • 2026-09-19 11:26:06
Linux HMM 共享虚拟内存SVM 架构及工作原理

摘要

本文系统分析 AMD GPU 计算栈中 KFD(Kernel Fusion Driver,亦称 amdkfd)子系统所实现的 SVM(Shared Virtual Memory,共享虚拟内存)机制。重点阐述其基于 Linux HMM(Heterogeneous Memory Management)框架的地址空间共享模型、GPU 页错误(retry fault)处理流程、MMU notifier 驱动的地址一致性维护,以及跨设备内存迁移策略,并结合工作流程图说明各模块间的协同关系。


1 引言

在异构计算体系中,CPU 与 GPU 传统上各自维护独立的虚拟地址空间,数据交换依赖显式的内存拷贝(hipMemcpy/clEnqueueWriteBuffer)与固定映射(pinned memory)。这种模型编程复杂、迁移开销大,难以支撑指针链表、图结构等不规则数据结构的高效跨设备访问。

KFD 是 Linux amdgpu 内核驱动中负责计算队列管理与用户态直接提交(user-mode queue submission)的子模块,ROCm 运行时通过 /dev/kfd 与之交互。SVM 是 KFD 在此基础上提供的地址空间统一能力,使 GPU 可以直接解引用一段与 CPU 进程共享的虚拟地址,由内核按需完成物理页的绑定与迁移。


2 背景机制

2.1 HMM 框架

Linux HMM 提供两类核心能力:

  • • hmm_range_fault:允许设备驱动查询一段虚拟地址对应的物理页帧,若页面不在内存中(换出或从未分配),触发常规缺页处理后再返回。
  • • 镜像页表(mirror page table):设备驱动维护一份与 CPU 页表逻辑一致的映射表,通过 mmu_notifier 感知 CPU 侧的失效/迁移事件,保持二者同步。

2.2 IOMMU 与 ATC

MI 系列等支持 SVM 的 AMD GPU 依赖 IOMMUv2 提供的 ATS/PRI(Address Translation Service / Page Request Interface):GPU 可直接使用进程的 CPU 虚拟地址发起访存,若地址未映射,通过 PRI 向 IOMMU 发起页请求,IOMMU 转发给内核缺页处理路径,处理完成后回填并唤醒等待的 GPU wavefront。

2.3 XNACK 机制

GPU 硬件对未就绪页面的访问会返回 XNACK(重试应答),指令流水线挂起对应 wavefront 而非直接产生致命异常,待内核完成映射后由硬件自动重放访存请求。这是 SVM“按需缺页”得以实现的硬件基础。


3 KFD 中的 SVM 架构

硬件内核态 amdgpu/KFD用户态PRI 页请求缺页事件应用程序 / ROCm Runtimelibhsakmt / KFD ioctl 接口kfd_svm 管理层svm_range 结构MMU Notifier地址失效回调hmm_range_fault页表查询页面迁移引擎System RAM <-> VRAMGPU 页表管理gmc/vm 模块IOMMUv2 ATS/PRIGPU 计算单元

3.1 核心数据结构

  • • svm_range:描述一段注册为 SVM 的虚拟地址区间,记录其当前驻留位置(System RAM 或某块 VRAM)、优先级提示(prefetch/preferred location)以及关联的 mm_struct。
  • • svm_range_list:每个进程一份,以区间树(interval tree)组织所有 svm_range,支持地址重叠查询与合并。
  • • kfd_process:进程级上下文,持有 SVM 区间列表及与之绑定的多个 GPU 设备的页表实例。

3.2 注册路径

应用通过 HSA_MEM_ALLOC 或 hipMallocManaged/hsaKmtSVMSetAttr 等接口注册地址区间,KFD 在 svm_range_list 中插入对应节点,但此时并不立即建立 GPU 页表映射——真正的映射延迟到首次访存触发缺页时才进行,体现“按需”特性。


4 页错误处理流程(核心工作原理)

CPU 内存管理HMM (hmm_range_fault)KFD SVM 处理线程IOMMU (ATS/PRI)GPU WavefrontCPU 内存管理HMM (hmm_range_fault)KFD SVM 处理线程IOMMU (ATS/PRI)GPU Wavefrontalt[需要迁移到显存]访问未映射地址返回 XNACK,挂起 wavefront发起 PRI 页请求 (page fault)在 svm_range 中定位对应区间hmm_range_fault(地址范围)若页面不在内存,触发常规缺页返回物理页帧 (PFN)返回页表项发起 migrate_vma 迁移至 VRAM更新 GPU 页表 (gmc/vm)回填映射,发送 Page Response重放访存请求wavefront 恢复执行

关键点说明:

  1. 1. 异步性:整个流程由内核工作队列(workqueue)异步处理,不阻塞其他 wavefront,保证 GPU 整体吞吐。
  2. 2. 迁移决策:KFD 根据访问热度、preferred_location 属性以及 XNACK 重试统计,决定页面是留在系统内存(通过 ATS 直接访问)还是迁移到本地 VRAM(通过 migrate_vma_setup/migrate_vma_pages 完成,底层使用 DMA 引擎拷贝)。
  3. 3. 粒度:迁移以 2MB 大页为倾向粒度,减少页表项数量与迁移次数,但也支持 4KB 粒度回退。

5 地址一致性维护:MMU Notifier

CPU 侧对页面的任何变更(munmap、mprotect、swap-out、THP 拆分、NUMA 迁移等)都会触发 mmu_notifier 回调链:

CPU 侧内存事件munmap/swap/迁移mmu_notifier_invalidate_rangeKFD svm_range 失效回调使对应 GPU 页表项失效下次 GPU 访问重新触发缺页

这保证了 GPU 页表始终是 CPU 页表的"最终一致"镜像:GPU 不会持有已被 CPU 释放或迁移的陈旧物理地址映射,避免出现"野指针"式的跨设备内存踩踏。


6 关键工程权衡


       
         
           
           
         
维度设计选择收益代价
缺页触发时机首访问才建立映射节省预注册开销、支持超额订阅首次访问延迟(cold fault)
迁移粒度2MB 大页优先减少页表项、提升 TLB 命中可能过度迁移(false sharing)
一致性维护MMU notifier 主动失效严格一致性、避免踩踏频繁失效带来的抖动开销
硬件依赖依赖 XNACK/ATS/PRI无需驱动轮询,硬件级重放仅特定架构(如 MI 系列)支持
       

     

7 与传统显式管理模型的对比

  • • 显式拷贝模型(hipMalloc + hipMemcpy):地址空间独立,迁移时机由程序员完全控制,峰值性能可预测,但编程复杂、无法支持超额订阅。
  • • SVM 模型:地址空间统一,迁移由内核按访问模式自动决策,显著简化编程模型,支持比显存更大的工作集,但引入缺页延迟与迁移抖动的不确定性,对访存局部性差的负载可能出现性能倒退(thrashing)。

二者并非互斥——ROCm 运行时通常允许在同一进程中混合使用,由开发者针对关键路径显式管理,非关键路径使用 SVM 简化开发。


8 结论

KFD 的 SVM 子系统本质上是 HMM 通用异构内存管理框架 + AMD GPU 硬件级页请求重放能力(XNACK/ATS/PRI) 的结合体:前者提供软件层面的地址空间镜像与一致性维护逻辑,后者提供硬件层面"缺页可重放"的执行语义,二者共同将传统上需要程序员显式管理的跨设备内存一致性问题下沉到内核与硬件协同处理,是当前 GPU 计算栈向"类 NUMA"统一内存模型演进的代表性实现路径。

最新文章

随机文章