AMD KFD的BO设计分析系列5-1:kgd_mem 实现详解
1. 设计背景与作用
在 AMD ROCm 平台的内核驱动体系中,kgd_mem
结构体是 KFD(Kernel Fusion Driver)与底层 GPU 驱动(AMDGPU)之间用于管理用户空间分配的 GPU 内存对象的桥梁。它抽象了用户进程在 GPU 上分配的显存、GTT、doorbell、userptr 等多种类型的内存资源,并负责这些资源的生命周期、映射、同步和多进程访问控制。
kgd_mem
的设计目标是为 KFD 进程提供统一的内存管理接口,支持多种内存类型、跨进程共享、DMA-BUF 导入导出、MMU 通知、同步机制等复杂功能,满足异构计算和高性能 GPU 任务的需求。
一句话总结:kgd_mem在KFD中的功能和地位就是amdgpu_bo在KGD中的位置和地位。
2. 结构体成员功能详解
struct kgd_mem {struct mutex lock; // 保护并发访问struct amdgpu_bo *bo; // 指向底层 GPU buffer objectstruct dma_buf *dmabuf; // DMA-BUF 对象,支持跨进程/设备共享struct hmm_range *range; // HMM 区间,支持页迁移和 SVMstruct list_head attachments; // 所有映射关系链表struct list_head validate_list; // 校验和同步链表uint32_t domain; // 内存域(VRAM/GTT/SYSTEM)unsigned int mapped_to_gpu_memory; // 已映射到GPU地址空间的数量uint64_t va; // 虚拟地址uint32_t alloc_flags; // 分配属性标志uint32_t invalid; // 是否失效(驱逐/迁移等)struct amdkfd_process_info *process_info; // 所属 KFD 进程信息struct amdgpu_sync sync; // fence 同步对象uint32_t gem_handle; // DRM/GEM 层 handlebool aql_queue; // 是否为 AQL 队列专用内存bool is_imported; // 是否通过 DMA-BUF 导入
};
2.1 基本资源管理
lock:保护
kgd_mem
对象的并发访问,确保多线程/多进程安全。bo:指向底层的
amdgpu_bo
(Buffer Object),代表实际分配的 GPU 显存或 GTT 内存。所有物理内存分配、页表映射等操作都依赖于该对象。dmabuf:指向 DMA-BUF 对象,支持跨进程、跨设备共享 GPU 内存。通过 DMA-BUF fd,可以在不同进程或驱动间传递和映射该内存。
range:指向 HMM(Heterogeneous Memory Management)区间,用于支持 SVM(共享虚拟内存)和页迁移等高级特性。
2.2 多类型内存支持与映射管理
attachments:维护所有与该内存对象相关的映射关系(
kfd_mem_attachment
),支持多种 attachment 类型(共享、userptr、dmabuf、SG 等),实现多进程/多设备映射和访问。validate_list:用于内存校验和同步,确保内存对象在 GPU 访问前已正确映射和分配。
domain:标记内存所属的物理域(如 VRAM、GTT、SYSTEM),便于驱动根据需求分配和管理资源。
mapped_to_gpu_memory:标记该内存对象是否已映射到 GPU 地址空间,便于后续访问和同步。
va:记录该内存对象在 GPU 虚拟地址空间中的起始地址,支持多进程虚拟地址隔离和映射。
alloc_flags:记录分配时的属性标志(如 VRAM、GTT、USERPTR、DOORBELL 等),决定底层分配和映射策略。
2.3 状态与生命周期管理
invalid:标记该内存对象是否已失效(如被驱逐、页迁移、MMU 通知等),驱动可据此进行回收或重映射。
process_info:指向所属 KFD 进程的信息结构体,便于多进程资源管理和同步。
sync:内部同步对象(
amdgpu_sync
),用于管理与该内存相关的 fence,确保命令提交和内存访问的正确顺序。gem_handle:该内存对象在 DRM/GEM 层的 handle,便于用户空间通过 fd 访问和管理。
aql_queue:标记该内存对象是否为 AQL(AMD Queue Language)队列专用内存,影响调度和同步策略。
is_imported:标记该内存对象是否通过 DMA-BUF 导入,影响生命周期和资源管理。
3. 生命周期管理与关键操作
1. 分配与初始化
用户空间通过 KFD ioctl(如
AMDKFD_IOC_ALLOC_MEMORY_OF_GPU
)请求分配 GPU 内存,驱动根据alloc_flags
创建对应的kgd_mem
对象。根据类型(VRAM/GTT/USERPTR/DOORBELL),驱动调用底层
amdgpu_bo_create
、amdgpu_bo_import
、amdgpu_bo_userptr
等接口分配物理内存,并初始化bo
、dmabuf
、va
等成员。
2. 映射与多进程共享
通过
attachments
链表,支持多进程或多设备对同一kgd_mem
的映射。每个 attachment 记录映射类型、地址、flags 等信息。支持 DMA-BUF 导入导出,实现跨进程、跨驱动共享显存。
3. 校验与同步
通过
validate_list
和sync
,在命令提交前校验内存对象的有效性和同步状态,确保 GPU 访问的正确性。fence 机制保证命令执行和内存访问的先后顺序,防止数据竞争和越界访问。
4. 失效与回收
当内存对象被驱逐、页迁移或 MMU 通知时,
invalid
标志被设置,驱动可据此进行资源回收或重新映射。结合
process_info
,实现进程级的资源回收和同步,提升系统健壮性。
5. 释放与销毁
用户空间释放内存对象时,驱动销毁
kgd_mem
,释放所有 attachment、bo、dmabuf 等资源,解除与进程的关联。
4. 与 KFD/AMDGPU 的协作机制
1. KFD 进程资源管理
每个 KFD 进程维护自己的
process_info
,其中包含所有分配的kgd_mem
对象和相关 BO 列表。进程销毁时,统一回收所有
kgd_mem
资源,防止内存泄漏和资源悬挂。
2. MMU 通知与页迁移
通过 HMM 和 MMU notifier 机制,
kgd_mem
支持用户空间页迁移、失效通知和 GPU page fault 处理。当用户空间内存发生变化时,驱动可及时更新 GPU 映射,保证数据一致性。
3. DMA-BUF 支持
kgd_mem
支持通过 DMA-BUF fd 导入/导出显存,实现多进程、多设备间的高效数据共享。通过
is_imported
标志区分本地分配和外部导入,影响资源管理和生命周期。
4. Fence 与同步机制
内部
amdgpu_sync
管理所有与该内存对象相关的 fence,确保命令提交和内存访问的正确顺序。支持多 ring、异步任务的同步需求,提升 GPU 任务调度效率。
5. 总结
kgd_mem
结构体是 KFD/AMDGPU 驱动内存管理的核心抽象,承载了多类型内存分配、映射、同步、生命周期管理等复杂功能。
结合 SVM、DMA-BUF、HMM 等机制,进一步提升多进程、跨设备的内存管理能力。
优化 fence 和同步机制,支持更高并发和更复杂的任务调度场景。
加强 MMU 通知和页迁移支持,提升系统容错和数据一致性。