欢迎光临
我们一直在努力

5.4 AMD KFD SVM:完整的双向迁移实现

KFD SVM 围绕 ROCm/HSA 运行时,把 CPU↔VRAM 双向迁移、GPU fault 恢复、CPU fault 回迁和多 GPU 访问策略整合在同一个 SVM 管理器里。

主要源码:

  • kfd_svm.c – range 管理、notifier、GPU fault、GPU mapping
  • kfd_migrate.c – RAM↔VRAM 迁移、SDMA copy、dev_pagemap
  • kfd_ioctl.h – SVM ioctl 属性定义

1 背景与 UAPI

KFD SVM 与 Xe SVM 的差异:KFD 直接维护 svm_range,用户态 ABI 是属性模型而非 VM bind。

1.1 属性驱动模型

struct kfd_ioctl_svm_args {
__u64 start_addr;
__u64 size;
__u32 op; // SET_ATTR / GET_ATTR
__u32 nattr;
struct kfd_ioctl_svm_attribute attrs[];
};

核心属性:

  • PREFERRED_LOC / PREFETCH_LOC:首选/预取位置
  • ACCESS / ACCESS_IN_PLACE / NO_ACCESS:GPU 访问权限
  • GRANULARITY:迁移粒度(log2 页数)

设置 PREFETCH_LOC 会触发即时迁移。


2 核心结构

2.1 svm_range

struct svm_range {
unsigned long start, last; // 页号范围
struct interval_tree_node it_node; // interval tree
struct mmu_interval_notifier notifier;
uint32_t preferred_loc, prefetch_loc, actual_loc;
DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
struct svm_range_bo *svm_bo; // VRAM backing
atomic_t invalid;
};

svm_range 既是 HMM mirror range,也是 KFD policy object。

2.2 VRAM dev_pagemap

// kfd_migrate.c
pgmap->type = MEMORY_DEVICE_PRIVATE; // 或 COHERENT(XGMI to CPU)
pgmap->ops = &svm_migrate_pgmap_ops;
-> .migrate_to_ram = svm_migrate_to_ram // CPU fault 回迁入口


3 RAM→VRAM 迁移

触发:PREFETCH_LOC 属性设置 或 GPU retry fault。

svm_migrate_to_vram(prange, best_loc, start, last, mm, trigger)
-> svm_migrate_ram_to_vram()

3.1 migrate_vma 三阶段

// 1. 收集系统页
migrate.flags = MIGRATE_VMA_SELECT_SYSTEM;
migrate_vma_setup(&migrate);

// 2. 分配 VRAM device page,SDMA 拷贝
dst[i] = svm_migrate_addr_to_pfn(adev, vram_offset);
svm_migrate_copy_to_vram(); // GART map + amdgpu_copy_buffer

// 3. 完成页表切换
migrate_vma_pages(&migrate);
migrate_vma_finalize(&migrate);


4 VRAM→RAM 迁移

触发:CPU 访问 device private page。

// pgmap callback
svm_migrate_to_ram(vmf)
-> svm_bo = vmf->page->zone_device_data // 反查 svm_range_bo
-> prange = svm_range_from_addr()
-> svm_migrate_vram_to_ram(prange, mm, start, last, ...)

按 granularity 对齐回迁范围,SDMA 反向拷贝后恢复系统 PTE。


5 GPU Fault 恢复

// amdgpu_vm.c
amdgpu_vm_handle_fault()
-> svm_range_restore_pages(adev, pasid, vmid, node_id, addr, ts, write)

5.1 best restore location

best_loc = svm_range_best_restore_location(prange, node, &gpuidx);
// 规则:preferred_loc > 同 XGMI hive > ACCESS bitmap > 回退 CPU

5.2 迁移 + 重建映射

if (best_loc)
svm_migrate_to_vram(prange, best_loc, ...);
else
svm_migrate_vram_to_ram(prange, ...);

svm_range_validate_and_map(mm, start, last, prange, gpuidx, ...);
-> amdgpu_hmm_range_get_pages() // HMM 取页
-> svm_range_dma_map() // DMA/VRAM 地址
-> svm_range_map_to_gpu() // 写 GPU PTE


6 CPU Invalidation

svm_range_cpu_invalidate_pagetables(mni, range, cur_seq)

6.1 XNACK on/off 分叉

if (!p->xnack_enabled || always_mapped) {
// 暂停队列,restore_work 重建
atomic_inc(&prange->invalid);
kgd2kfd_quiesce_mm(mm);
queue_delayed_work(&svms->restore_work);
} else {
// 直接 unmap,靠 retry fault 恢复
svm_range_unmap_from_gpus(prange, ...);
}

6.2 restore_work

svm_range_restore_work()
-> svm_range_validate_and_map() // 重建所有 invalid range
-> kgd2kfd_resume_mm() // 恢复队列


7 总结

KFD SVM 核心流程:

  • 属性驱动:preferred_loc / access bitmap / granularity 决定迁移策略
  • RAM→VRAM:migrate_vma + SDMA 拷贝 + device private page
  • VRAM→RAM:pgmap migrate_to_ram + SDMA 反向拷贝
  • GPU fault:按 PASID/node/XNACK/best_loc 迁移并重建 GPU PTE
  • CPU invalidation:XNACK on 直接 unmap;XNACK off 暂停队列后 restore
  • 源文件重点
    kfd_svm.c range 管理、notifier、fault restore、GPU mapping
    kfd_migrate.c migrate_vma、SDMA copy、dev_pagemap
    kfd_chardev.c SVM ioctl 入口
    amdgpu_vm.c GPU fault 调用 svm_range_restore_pages

    📚 关联阅读

    • 01 – 什么是SVM
    • AMD ROCm-SVM技术的实现与应用深度分析:详细分析AMD KFD SVM实现的专栏
    赞(0)
    未经允许不得转载:171主机测评 » 5.4 AMD KFD SVM:完整的双向迁移实现
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址