AMD KFD的BO设计分析系列3-1: GTT的实现分析
1. 前言
前面两篇文章,概括性地分析了GEM与TTM的结构和关系。文章链接如下:
AMD KFD的BO设计分析系列1-1:DRM GEM显存管理原理篇
AMD KFD的BO设计分析系列2-1:TTM与GEM的关系
本篇开始分析TTM里的GTT技术。AMDGPU 驱动作为 Linux 下 AMD 显卡的主线驱动,采用了多层次的内存管理体系。其中,AMD GTT(Graphics Translation Table)是 AMD GPU 驱动(如 amdgpu、radeon)中用于管理主机系统内存(即“系统内存”或“GART”)的一种机制。GTT 允许 GPU 通过 IOMMU 或内置的地址重映射单元访问主内存,实现大容量、可分页的显存支持。GTT 机制不仅支撑了大部分 BO(Buffer Object)的分配、迁移和回收,还为 GPU 虚拟内存、统一寻址、页迁移等高级特性提供了基础。本文将以源码为基础,系统分析 AMDGPU GTT 的实现原理、初始化流程、GTT BO 的创建与管理机制。
2. GTT 的基本概念与作用
GTT(Graphics Translation Table)本质上是 GPU 侧的页表(Page Table),用于将 GPU 虚拟地址映射到主机物理内存。在 AMDGPU 驱动中,GTT 主要指代系统内存(System Memory)区域,通过 GART(Graphics Address Remapping Table)机制实现 GPU 对主机内存的访问。有如下用途:
-
支持大容量内存:GTT 允许 GPU 访问超出显存容量的主机内存,提升大数据集处理能力。
-
统一寻址:为 GPU 提供统一的虚拟地址空间,简化内存管理和数据迁移。
-
页迁移与回收:支持 BO 在 VRAM 和 GTT 之间动态迁移,提升内存利用率。
-
多进程/多任务支持:为每个进程/任务分配独立的 GTT 区域,提升安全性和隔离性。
3. GTT 管理的核心数据结构
3.1 amdgpu_gtt_mgr
amdgpu_gtt_mgr
是 GTT 管理器的核心结构体,负责 GTT 区域的分配、回收和管理。其定义如下:
struct amdgpu_gtt_mgr {struct ttm_resource_manager manager;struct drm_mm mm;spinlock_t lock;
};
-
manager:TTM(Translation Table Manager)资源管理器,负责与 TTM 框架对接。
-
mm:
drm_mm
结构体,负责 GTT 区间的分配与回收。 -
lock:自旋锁,保护 GTT 区间分配的并发安全。
对比AMD KFD的BO设计分析系列2-1:TTM与GEM的关系的ttm_range_manager定义,可以发现amdgpu_gtt_mgr和ttm_range_manager完全一致,就是换了个结构体名称。那请读者思考,是不是可以不用定义这个amdgpu_gtt_mgr
而直接使用ttm_range_manager呢?
2. ttm_resource_manager
TTM 框架的资源管理器,抽象了不同类型内存(如 VRAM、GTT、SYSTEM)的分配与管理。GTT 管理器通过继承和实现 ttm_resource_manager_func
接口,与 TTM 框架无缝集成。
3. ttm_range_mgr_node
GTT 区间的分配单元,每个 BO 在 GTT 中分配一个或多个 ttm_range_mgr_node
,用于描述其在 GTT 地址空间中的起始地址、大小等信息。
ttm_resource_manager和ttm_range_mgr_node的具体实现请参见:TTM实现的详细分析。
4. GTT 的初始化流程
GTT 的初始化主要在 amdgpu_gtt_mgr_init
函数中完成,流程如下:
4.1 结构体初始化
struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
struct ttm_resource_manager *man = &mgr->manager;
-
获取 GTT 管理器和 TTM 资源管理器指针。
4.2 设置管理器属性
man->use_tt = true;
man->func = &amdgpu_gtt_mgr_func;
-
指定该管理器用于 TT(Translation Table)类型内存。
-
绑定 GTT 管理器的操作函数集(分配、释放、兼容性检查等)。
3. 初始化 TTM 资源管理器
ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
- 初始化 TTM 资源管理器,指定管理的 BO 设备和 GTT 总大小。
4. 初始化 GTT 区间分配器
start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
drm_mm_init(&mgr->mm, start, size);
spin_lock_init(&mgr->lock);
- 计算 GTT 区间的起始地址和总页数,预留部分空间用于 DMA 传输窗口。
- 初始化
drm_mm
区间分配器和自旋锁。
5. 注册到 TTM 框架
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
ttm_resource_manager_set_used(man, true);
- 将 GTT 管理器注册到 TTM 框架,标记为可用。
可以看到GTT 的初始化流程充分利用了 TTM 和 DRM 框架的分层设计,实现了高效、可扩展的内存管理。
5.BO(Buffer Object)的创建与 GTT 分配
5.1 BO 创建流程
BO(Buffer Object)是 GPU 内存管理的基本单元,代表一块可被 GPU/CPU 访问的内存区域。回顾下BO 的创建流程如下:
-
用户空间通过 ioctl 请求分配 BO,指定大小、对齐、内存类型(如 VRAM、GTT)。
-
驱动调用 TTM 框架的分配接口,如
ttm_bo_init
,传入 BO 属性和期望的内存类型。 -
TTM 框架根据内存类型选择对应的资源管理器(如 GTT 管理器)。
-
GTT 管理器分配 GTT 区间,为 BO 分配一段连续的 GTT 地址空间,并返回
ttm_resource
结构体。 -
BO 结构体记录分配结果,包括 GTT 区间的起始地址、大小、页表映射等信息。
5.2 GTT 区间分配实现
GTT 区间的分配由 amdgpu_gtt_mgr_new
实现,流程如下:
-
分配
ttm_range_mgr_node
结构体,作为 GTT 区间的描述单元。 -
调用
ttm_resource_init
初始化资源属性。 -
检查 GTT 使用量是否超限,防止超分配。
-
如果指定了分配范围(如
place->lpfn
),则加锁后调用drm_mm_insert_node_in_range
在 GTT 地址空间中分配区间。 -
记录分配结果到
node->base.start
。 -
返回分配的
ttm_resource
指针。
3. GTT 区间释放
GTT 区间的释放由 amdgpu_gtt_mgr_del
实现,流程如下:
-
加锁后检查区间是否已分配,若已分配则调用
drm_mm_remove_node
释放。 -
调用
ttm_resource_fini
清理资源。 -
释放
ttm_range_mgr_node
结构体。
4. BO 与 GTT 的关系
-
每个 BO 在 GTT 中分配一个或多个区间,记录在
ttm_resource
结构体中。 -
BO 的物理页通过页表(GART)映射到 GTT 区间,实现 GPU 对主机内存的访问。
-
BO 支持在 VRAM 和 GTT 之间动态迁移,提升内存利用率和性能。
6.GTT 的管理与查询
1. GTT 使用量统计
AMDGPU 驱动通过 sysfs 提供 GTT 总量和已用量的查询接口:
-
/sys/class/drm/cardX/device/mem_info_gtt_total
:GTT 总容量。 -
/sys/class/drm/cardX/device/mem_info_gtt_used
:GTT 已用容量。
实现方式为读取 ttm_resource_manager
的 size
和 ttm_resource_manager_usage
。
2. GTT 区间的兼容性与交集检查
-
amdgpu_gtt_mgr_intersects
和amdgpu_gtt_mgr_compatible
用于判断两个资源是否有交集或兼容,便于碎片整理和分配优化。
3. GTT 区间调试与恢复
-
amdgpu_gtt_mgr_debug
可打印当前 GTT 区间分配情况,便于调试。 -
amdgpu_gtt_mgr_recover
支持 GART 恢复,遍历所有已分配 BO,重新初始化页表映射,提升容错能力。
7. GTT 的高级特性与优化
1. 动态迁移与回收
-
支持 BO 在 VRAM 和 GTT 之间动态迁移,提升内存利用率。
-
支持内存回收和 swap,防止 OOM。
2. 多进程/多任务支持
-
为每个进程/任务分配独立的 GTT 区域,提升安全性和隔离性。
-
支持多队列、多上下文的高效调度。
3. 大页与对齐优化
-
支持大页分配和对齐,提升内存访问效率。
4. 容错与恢复
-
支持 GART 恢复和 BO 重新映射,提升系统容错能力。
8. 总结
AMDGPU GTT 管理机制以 TTM 和 DRM 框架为基础,采用分层、模块化设计,实现了高效、可扩展的主机内存管理。通过 GTT 管理器、区间分配器、BO 生命周期管理等机制,驱动能够灵活应对多种内存类型、动态迁移、容错恢复等复杂场景。理解 GTT 的实现原理和管理机制,是深入掌握 AMDGPU 驱动开发和 GPU 内存管理架构的基础。