AMD KFD的BO设计分析系列5-2:VM-amdgpu_vm_bo

在开篇介绍时,我说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 的扩展结构中的。

具体流程如下:

  1. BO 创建时不会自动分配 amdgpu_vm_bo_base
    普通的 amdgpu_bo 创建(如用户空间显存分配、内核 BO 创建)时,仅分配和初始化 amdgpu_bo 结构体本身,不会自动包含任何 VM 相关信息。

  2. VM 映射时分配和关联
    当某个 BO 需要被映射到某个 VM(如进程 GPU 虚拟地址空间),驱动会为该 BO 和 VM 的关联关系分配一个 amdgpu_vm_bo_base 结构体,并将其加入到 BO 的扩展链表或和VM 的管理链表中。典型场景包括:

    • 用户空间通过 ioctl 映射 BO 到 GPU 虚拟地址空间

    • KFD 进程分配/映射显存

    • 页表更新、迁移、驱逐等 VM 操作

         相关代码通常在 amdgpu_vm_bo_addamdgpu_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_movelist_addlist_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 的关联和状态。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeeplyMind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值