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前,我先把核心观点说一下:kgd_mem 是在 amdgpu_bo 基础上,针对 AI 计算场景进行业务扩展的内存对象,其在 KFD(Kernel Fusion Driver)中的功能和地位,正如 amdgpu_bo 在 KGD(Kernel Graphics Driver)中的作用和定位。
但不知道为什么这个结构体用了kgd_打头,感觉整个KFD代码中的其他用kfd_打头的结构体格格不入。我在想是不是最初AMD在开发时也没有想好要干啥。真建议AMD驱动开发人员思考下这个问题。但你可以这样理解:因为KFD(Kernel Fusion Driver)和 KGD(Kernel Graphics Driver)在 AMD GPU 驱动架构中分别承担不同的角色,但它们需要在内核层进行协作。
kgd_mem采用kgd_前缀,表示它是 KGD(即 amdgpu 驱动)侧定义的、用于 KFD 访问的内存对象。KGD 负责底层显卡资源管理,KFD 负责异构计算(如 ROCm/HSA)。- KFD 代码中的结构体通常用
kfd_前缀,表示它们属于 KFD 内部的数据结构和逻辑。
这种前缀区分是为了明确接口归属和模块边界:
kgd_前缀的结构体是 KFD 与 KGD 之间的“桥梁”或接口对象,供 KFD 调用和管理底层显卡资源。kfd_前缀的结构体则是 KFD 自己的业务实现,与 KGD 的接口对象区分开来。
因此,kgd_mem 虽然被 KFD 使用,但它属于 KGD(amdgpu)侧的定义,前缀不同是为了体现模块分工和接口清晰,而不是风格不统一。
扯远了,书归正转。
2. 结构体成员功能详解
struct kgd_mem {
struct mutex lock; // 保护并发访问
struct amdgpu_bo *bo; // 指向底层 GPU buffer object
struct dma_buf *dmabuf; // DMA-BUF 对象,支持跨进程/设备共享
struct hmm_range *range; // HMM 区间,支持页迁移和 SVM
struct 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 层 handle
bool 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 通知和页迁移支持,提升系统容错和数据一致性。
技术交流,欢迎加入社区:GPUers。
AMD KFD中kgd_mem内存管理解析
811

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



