AMD KFD的BO设计分析系列5-3:VM-amdgpu_bo_va_mapping
1. 概念解释
amdgpu_bo_va_mapping
是 AMDGPU 驱动中用于描述一个 BO(Buffer Object)在某个 VM(虚拟地址空间)中的具体虚拟地址映射关系的数据结构。它的使用时机和代码调用点主要围绕 GPU 虚拟内存管理、显存映射、页表维护等场景。
struct amdgpu_bo_va_mapping {struct amdgpu_bo_va *bo_va; // 指向该映射所属的 BO-VA 对象(BO 在 VM 中的描述)struct list_head list; // 用于挂载到 BO-VA 的映射链表(如 invalids/valids)struct rb_node rb; // 红黑树节点,用于插入 VM 的 interval tree,便于地址查找uint64_t start; // 映射区间的起始页号(GPU 虚拟地址空间)uint64_t last; // 映射区间的结束页号(GPU 虚拟地址空间)uint64_t __subtree_last; // interval tree 用于快速查找的辅助字段(最大结束页号)uint64_t offset; // 映射到 BO 的偏移(BO 内部的起始位置)uint64_t flags; // 映射属性标志(如读/写/PRT/有效等)
};
2.使用时机
BO 映射到 VM 时
当用户空间或内核需要将某个 BO 映射到 GPU 虚拟地址空间(如通过 ioctl 或 KFD/HSA runtime),驱动会创建一个
amdgpu_bo_va_mapping
实例,描述该 BO 的哪一段物理内存被映射到 VM 的哪个虚拟地址区间。典型场景:OpenCL/Vulkan 显存分配、图形渲染缓冲区映射、KFD 进程显存管理。
虚拟地址空间管理和页表更新时
每次 BO 的映射、迁移、驱逐、失效等操作,都会涉及到
amdgpu_bo_va_mapping
的创建、插入、删除或状态迁移。页表更新时,驱动遍历所有相关的
amdgpu_bo_va_mapping
,批量更新 PTE(页表项)。
映射冲突检测和 interval tree 管理时
驱动通过 interval tree(红黑树)管理所有
amdgpu_bo_va_mapping
,实现虚拟地址区间的高效查找和冲突检测。
3. 主要代码调用点
amdgpu_vm_bo_map
这是 BO 映射的核心接口。每次调用都会分配一个新的 amdgpu_bo_va_mapping
,并设置其起始地址、结束地址、offset、flags 等。
mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
mapping->start = saddr;
mapping->last = eaddr;
mapping->offset = offset;
mapping->flags = flags;
amdgpu_vm_bo_insert_map(adev, bo_va, mapping);
amdgpu_vm_bo_unmap
当需要解除 BO 的映射时(如显存回收、进程退出),会查找并删除对应的 amdgpu_bo_va_mapping
,并更新 VM 的 interval tree 和状态链表。
页表更新相关函数
如 amdgpu_vm_update_range
、amdgpu_vm_bo_update
,会遍历所有 amdgpu_bo_va_mapping
,批量更新页表项,确保 GPU 虚拟地址空间与物理内存的一致性。
映射冲突检测
在映射新 BO 前,驱动会通过 interval tree 查找是否有冲突的 amdgpu_bo_va_mapping
,防止虚拟地址区间重叠。
状态迁移与调试
amdgpu_bo_va_mapping
还会参与 BO 状态链表的迁移(如 invalids、valids、moved、idle 等),并通过 trace 机制记录映射操作,便于调试和性能分析。
4.总结
amdgpu_bo_va_mapping
的使用时机贯穿于 BO 显存映射、虚拟地址空间管理、页表更新、冲突检测、状态迁移等所有 GPU 虚拟内存相关操作。其主要代码调用点集中在 BO 映射(amdgpu_vm_bo_map
)、插入(amdgpu_vm_bo_insert_map
)、解除映射(amdgpu_vm_bo_unmap
)、页表更新和 interval tree 管理等函数中,是 AMDGPU 虚拟内存系统的基础数据结构之一。