接上文:AMD KFD驱动技术分析11:SVM驱动实现-2。
经过与现有区间的重叠、拆分处理后,接下来就是按顺序处理各个list。
/* insert_list的处理 */
list_for_each_entry_safe(prange, next, &insert_list, list) {
svm_range_add_to_svms(prange);
svm_range_add_notifier_locked(mm, prange);
}
/* remove_list的处理 */
list_for_each_entry_safe(prange, next, &remove_list, update_list) {
pr_debug("unlink old 0x%p prange 0x%p [0x%lx 0x%lx]\n",
prange->svms, prange, prange->start,
prange->last);
svm_range_unlink(prange);
svm_range_remove_notifier(prange);
svm_range_free(prange, false);
}
mmap_write_downgrade(mm);
/* update_list的处理 */
list_for_each_entry(prange, &update_list, update_list) {
...
}
/* remap_list的处理 */
list_for_each_entry(prange, &remap_list, update_list) {
mutex_lock(&prange->migrate_mutex);
svm_range_validate_and_map(mm, prange->start, prange->last, prange,
MAX_GPU_INSTANCE, true, true, prange->mapped_to_gpu);
mutex_unlock(&prange->migrate_mutex);
}
insert_list的处理
将 insert_list 链表中的所有新建 SVM 区间(svm_range)正式插入到进程的 SVM 区间管理器(svm_range_list)和rb-tree,并为每个区间注册 MMU interval notifier,以便后续能感知虚拟内存的变化(如 unmap、迁移等)。
remove_list的处理
彻底清理所有被替换、被拆分、被合并的旧 SVM 区间,确保区间树、链表、MMU 通知器和内存资源都被正确释放。
update_list的处理
对 update_list 链表中的每个 SVM 区间(svm_range)进行迁移和/或 GPU 页表映射更新,以确保区间属性变更后,物理内存位置和 GPU 页表状态与新属性保持一致。它是 SVM 属性设置(如 prefetch、访问权限、标志位等)后端的核心处理流程。
详细功能分析如下:
-
遍历 update_list
list_for_each_entry(prange, &update_list, update_list)
遍历所有需要更新的 SVM 区间。 -
加锁保护
mutex_lock(&prange->migrate_mutex);
保证迁移和映射操作的串行化,防止并发冲突。 -
触发迁移
r = svm_range_trigger_migration(mm, prange, &migrated);- 根据区间的 prefetch 属性和实际位置,决定是否需要迁移(如 RAM→VRAM 或 VRAM→RAM)。
- 如果迁移发生,
migrated被置为 true。
-
迁移后特殊处理
如果迁移发生,且(1)xnack 未使能,或(2)区间设置了 GPU_ALWAYS_MAPPED,且区间已映射到 GPU,则跳过后续映射操作(因为 restore_work 会统一处理 GPU 页表更新)。 -
无需迁移且无需映射时跳过
如果没有迁移且不需要更新映射(!migrated && !update_mapping),直接跳过。 -
决定是否刷新 TLB
flush_tlb = !migrated && update_mapping && prange->mapped_to_gpu;- 如果没有迁移但需要更新映射,且区间已映射到 GPU,则需要刷新 TLB。
-
GPU 页表映射/更新
r = svm_range_validate_and_map(...)- 对区间进行 GPU 页表的映射或更新,确保 GPU 能正确访问该区间。
- 支持多 GPU,支持并发失效和恢复。
-
错误处理
- 如果迁移或映射失败,记录错误码,便于后续统一处理。
-
解锁
mutex_unlock(&prange->migrate_mutex);- 保证每个区间的迁移和映射操作结束后及时释放锁。
4.1.4 SVM 区间的映射与迁移
- 当 GPU 访问 SVM 区间时,若未映射或位置不对,会触发 page fault。
- 驱动通过
svm_range_restore_pages响应 page fault,决定最佳恢复位置(CPU/GPU),并调用svm_migrate_to_vram或svm_migrate_vram_to_ram进行数据迁移。 - 迁移完成后,调用
svm_range_validate_and_map更新 GPU 页表映射,保证 GPU 能正确访问数据。 - 支持多 GPU 协作和 NUMA/XGMI 拓扑下的高效迁移。
4.4 SVM 区间的失效与恢复
-
当 CPU 侧发生 unmap、migrate、page invalidation 等事件时,MMU 通知器回调
svm_range_cpu_invalidate_pagetables被触发。 -
对于 unmap 事件,驱动调用
svm_range_unmap_from_cpu,将区间从 GPU unmap,并通过延迟工作队列安全地移除区间。 -
对于迁移/失效事件,驱动调用
svm_range_evict,暂停相关 GPU 队列,等待 CPU 完成页表更新,然后通过svm_range_restore_work恢复区间映射和队列运行。
4.6 SVM 区间的 CRIU 支持
-
支持进程检查点/恢复(CRIU),通过
kfd_criu_checkpoint_svm、kfd_criu_restore_svm等接口保存和恢复 SVM 区间状态。 -
便于高性能计算和云场景下的进程热迁移。
5. KFD SVM 的代码实现要点
5.1 区间树与链表的高效管理
-
采用 Linux 内核的
interval_tree实现高效的区间查找、插入、删除,支持 O(logN) 级别的性能。 -
所有区间同时维护在链表中,便于遍历和批量操作。
5.2 MMU 通知器的集成
-
每个 SVM 区间注册
mmu_interval_notifier,感知虚拟内存的 unmap、迁移、失效等事件。 -
通知器回调中安全地暂停 GPU 队列、unmap 区间、恢复映射,保证数据一致性和系统稳定性。
5.3 多 GPU/NUMA/XGMI 支持
-
通过 bitmap 管理每个区间在多 GPU 下的访问权限和映射状态。
-
支持 XGMI hive 拓扑下的高效数据迁移和一致性管理。
-
兼容 APU/dGPU 混合场景,自动选择最佳迁移路径。
5.4 迁移与映射的同步机制
-
迁移和映射操作通过
migrate_mutex、lock等多级锁保护,防止并发冲突。 -
支持异步迁移、延迟恢复等机制,提升系统吞吐和响应能力。
5.5 事件与异常处理
-
支持 GPU page fault、eviction、unmap 等多种异常场景的自动处理。
-
通过工作队列和延迟任务,保证复杂操作在安全上下文中完成,避免死锁和竞态。
6. SVM 在 KFD 驱动中的优势与挑战
6.1 优势
-
高性能:消除 CPU-GPU 间冗余数据拷贝,提升带宽利用率。
-
易用性:应用开发者无需关心底层迁移和同步,专注于业务逻辑。
-
灵活性:支持多 GPU、NUMA、XGMI 等复杂拓扑,适应多样化硬件环境。
-
健壮性:完善的异常处理和恢复机制,保证系统稳定运行。
-
可扩展性:支持 CRIU、热迁移等高级特性,适合云和 HPC 场景。
6.2 挑战
-
一致性管理复杂:多 GPU/NUMA 下的数据一致性和同步难度大。
-
性能调优难:迁移策略、粒度、属性等参数需根据实际场景精细调优。
-
内核集成难度高:与 Linux MMU、TTM、AMDGPU 等子系统深度耦合,开发和维护门槛高。
-
异常场景多:如 page fault 风暴、死锁、资源泄漏等需精心设计和测试。
7. 典型业务流程举例
7.1 GPU 访问 CPU 分配的内存
- 应用分配内存(如 malloc),并通过 SVM ioctl 设置为 GPU 可访问。
- GPU 访问该内存,若未映射则触发 page fault。
- KFD 驱动捕获 fault,迁移数据到 GPU 显存或建立映射。
- GPU 继续访问,无需应用干预。
7.2 CPU 访问 GPU 分配的显存
-
应用通过 SVM ioctl 分配 VRAM buffer,并映射到进程虚拟地址空间。
-
CPU 直接访问该地址,KFD 驱动自动处理映射和权限。
-
支持数据回迁(migrate to RAM)和一致性同步。
7.3 多 GPU 协作
-
应用设置 SVM 区间为多 GPU 可访问。
-
KFD 驱动根据访问模式自动迁移数据,保证各 GPU 能高效访问。
-
支持 XGMI hive 下的高效数据共享和一致性。
8. 总结与展望
SVM 作为现代异构计算平台的核心技术,极大提升了 CPU-GPU 协作的效率和易用性。KFD 驱动通过精细的区间管理、MMU 通知器集成、多 GPU 支持、自动迁移与恢复等机制,实现了高性能、健壮、灵活的 SVM 支持。随着硬件和应用需求的不断发展,SVM 机制还将持续演进,支持更细粒度的共享、更智能的迁移策略、更强的安全与一致性保障。
对于驱动开发者和高性能计算工程师,深入理解 KFD SVM 的实现原理和关键流程,有助于开发更高效、可靠的异构计算应用,并为未来的系统优化和创新打下坚实基础。
技术交流,欢迎加入社区:GPUers。
2279

被折叠的 条评论
为什么被折叠?



