在开篇介绍时,我说amdgpu_bo分为两个部分:物理地址部分和虚拟地址部分。物理地址部分主要与ttm部分相关,具体的博文系列请参考:AMD KFD的BO设计分析系列3-2: Linux drm_mm在amdgpu bo创建过程中的应用。
本文开始分析虚拟地址部分。在这之前请先理解:AMDGPU_VM。
1. 设计背景与作用
在 AMDGPU 驱动的 GPU 虚拟内存(VM)管理体系中,amdgpu_vm_bo_base 结构体是连接虚拟地址空间(VM)与物理显存对象(BO, Buffer Object)的核心桥梁。它的设计目的是在 VM 内部高效、可靠地跟踪和管理所有与该 VM 相关的 BO,支持多进程隔离、显存统计、迁移、驱逐、同步等复杂操作。
每个 VM(即每个 GPU 虚拟地址空间,通常对应一个用户进程或 KFD 计算上下文)都可能映射多个 BO,而每个 BO 也可能被多个 VM 共享。amdgpu_vm_bo_base 负责维护这种多对多关系,并为 VM 的页表管理、资源统计、状态迁移等功能提供基础数据结构支持。
2. 结构体成员功能详解
struct amdgpu_vm_bo_base {
/* constant after initialization */
struct amdgpu_vm *vm; // 指向所属 VM
struct amdgpu_bo *bo; // 指向底层显存对象
/* protected by bo being reserved */
struct amdgpu_vm_bo_base *next; // 链表,支持多 BO 关联
/* protected by vm status_lock */
struct list_head vm_status; // 状态链表节点
/* if the bo is counted as shared in mem stats
* protected by vm status_lock */
bool shared; // 是否为共享 BO
/* protected by the BO being reserved */
bool moved; // 是否已迁移
};
1. vm
-
指向所属的
amdgpu_vm结构体,表示该 BO 属于哪个虚拟地址空间。 -
便于在 VM 级别进行资源统计、状态管理和页表维护。
2. bo
-
指向底层的
amdgpu_bo(Buffer Object),代表实际分配的显存或系统内存。 -
所有物理内存分配、页表映射等操作都依赖于该对象。
3. next
-
用于将多个
amdgpu_vm_bo_base连接成链表,支持 VM 内部多 BO 管理。 -
便于遍历和批量操作所有相关 BO。
4. vm_status
-
状态链表节点,挂载在 VM 的各种状态链表(如 evicted、moved、idle 等)上。
-
支持 BO 的状态迁移和生命周期管理。
5. shared
-
标记该 BO 是否为共享对象(即被多个 VM 共同引用)。
-
影响显存统计和驱逐策略,便于资源隔离和性能分析。
6. moved
-
标记该 BO 是否已迁移(如被驱逐或重新分配物理内存)。
-
迁移后需要更新页表,保证虚拟地址空间的正确性。
3. 生命周期管理与关键操作
amdgpu_vm_bo_base 是在 AMDGPU 虚拟内存(VM)系统需要将某个 BO(Buffer Object)映射到某个 VM(虚拟地址空间)时,由驱动动态分配并加入到 amdgpu_bo 的扩展结构中的。
具体流程如下:
-
BO 创建时不会自动分配 amdgpu_vm_bo_base
普通的amdgpu_bo创建(如用户空间显存分配、内核 BO 创建)时,仅分配和初始化amdgpu_bo结构体本身,不会自动包含任何 VM 相关信息。 -
VM 映射时分配和关联
当某个 BO 需要被映射到某个 VM(如进程 GPU 虚拟地址空间),驱动会为该 BO 和 VM 的关联关系分配一个amdgpu_vm_bo_base结构体,并将其加入到 BO 的扩展链表或和VM 的管理链表中。典型场景包括:-
用户空间通过 ioctl 映射 BO 到 GPU 虚拟地址空间
-
KFD 进程分配/映射显存
-
页表更新、迁移、驱逐等 VM 操作
-
相关代码通常在 amdgpu_vm_bo_add、amdgpu_vm_bo_map 等函数中实现。这些函数的实现请参见专文:amdgpu_vm_bo_map的实现。
3.1 初始化与关联
- 创建 BO 后,通过
amdgpu_vm_bo_base_init初始化amdgpu_vm_bo_base,并将其关联到 VM 和 BO。 - 典型流程:
void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
struct amdgpu_vm *vm, struct amdgpu_bo *bo)
{
base->vm = vm;
base->bo = bo;
base->next = NULL;
INIT_LIST_HEAD(&base->vm_status);
base->shared = false;
base->moved = false;
}
3.2 状态链表管理
-
VM 内部维护多种 BO 状态链表(如 evicted、moved、idle、invalidated 等),每个
amdgpu_vm_bo_base都可挂载在这些链表上。 -
状态迁移通过
list_move、list_add、list_del等操作实现,便于批量驱逐、回收和页表更新。
3.3 显存统计与共享管理
-
通过
shared标志,驱动可区分独占 BO 和共享 BO,影响显存统计和驱逐策略。 -
统计更新通过
amdgpu_vm_update_stats实现,支持 VRAM、GTT、SYSTEM 等多种内存类型。
3.4 迁移与驱逐
-
当 BO 被驱逐或迁移时,
moved标志被设置,驱动需更新页表并同步状态链表。 -
迁移操作通过
amdgpu_vm_bo_move实现,确保虚拟地址空间与物理内存的一致性。
3.5 释放与销毁
-
VM 或 BO 销毁时,需释放所有关联的
amdgpu_vm_bo_base,解除链表挂载,防止资源泄漏。
4. 与 AMDGPU 虚拟内存系统的协作机制
| 协作机制 | 简要说明 |
|---|---|
| VM 与 BO 的多对多关系 | 一个 VM 可映射多个 BO,一个 BO 也可被多个 VM 共享,amdgpu_vm_bo_base 作为桥梁管理关联关系。 |
| 页表管理与更新 | VM 页表需跟踪所有映射的 BO,amdgpu_vm_bo_base 提供基础数据结构,支持批量页表项更新。 |
| 状态迁移与同步 | VM 内部通过状态链表和锁机制,支持 BO 的迁移、驱逐、失效等操作,vm_status 节点便于批量管理。 |
| 显存统计与资源隔离 | 通过 shared 标志和统计接口,实现多进程显存隔离和资源回收,支持多种内存类型和分区。 |
5. 总结
amdgpu_vm_bo_base 是 AMDGPU 驱动虚拟内存管理的核心数据结构之一,承载了 VM 与 BO 的关联、状态管理、显存统计、迁移驱逐等多方面功能。amdgpu_vm_bo_base 是在 BO 被映射到 VM 时,由驱动动态分配并加入到 BO 的扩展结构或 VM 的管理链表中的,而不是在 BO 创建时自动分配。它用于管理 BO 与 VM 的关联和状态。
1162

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



