关联阅读:
- TTM 设计目标和核心概念 – 理解 TTM 的"统一管理异构内存域"设计目标
- 4.8.1 TTM Eviction 机制概述 – Placement 在 eviction 中的作用
1. 为什么需要 Placement?
4.1节我们说TTM 的核心设计目标之一是统一管理异构内存域(VRAM、GTT、SYSTEM 等)。但一个 BO 并不是只能住在一种内存里——它可能优先住 VRAM(性能最高),退而求其次住 GTT,最差住 SYSTEM。
Placement 就是 BO 对 TTM 说的一句话:“我可以住在这些地方,按这个优先级来。”
这直接服务于 TTM 的两大设计目标:
| 设计目标 | Placement 的作用 |
|---|---|
| 多内存域统一管理 | 用统一的ttm_placement结构描述 BO 在不同域中的放置偏好 |
| 显存动态调度与超配 | 当首选域满时,Placement 指示 TTM 可以降级到哪个域,驱动 eviction 和迁移决策 |
2. 数据结构
2.1ttm_placement– 放置策略
/* include/drm/ttm/ttm_placement.h */structttm_placement{unsignednum_placement;/* 候选域的数量 */conststructttm_place*placement;/* 候选域数组(按优先级排列)*/};ttm_placement是一个有序候选域列表。TTM 在分配资源时按数组顺序依次尝试,第一个成功的域就是 BO 的落脚点。
2.2ttm_place– 单个候选域描述
/* include/drm/ttm/ttm_placement.h */structttm_place{unsignedfpfn;/* 起始页帧号限制 (0 = 无限制) */unsignedlpfn;/* 结束页帧号限制 (0 = 无限制) */uint32_tmem_type;/* TTM_PL_VRAM / TTM_PL_TT / TTM_PL_SYSTEM */uint32_tflags;/* TTM_PL_FLAG_CONTIGUOUS 等 */};每个ttm_place描述一个候选内存域,并可附加约束:
| 字段 | 含义 | 典型用法 |
|---|---|---|
mem_type | 内存域类型 | TTM_PL_VRAM、TTM_PL_TT、TTM_PL_SYSTEM |
fpfn/lpfn | 页帧号范围限制 | 限制在 VRAM 的前 256MB(CPU 可见区域) |
flags | 放置标志 | 连续分配、DESIRED/FALLBACK 等 |
2.3 TTM 预定义的内存域常量
/* include/drm/ttm/ttm_placement.h */#defineTTM_PL_SYSTEM0/* 纯系统内存,GPU 不可直接访问 */#defineTTM_PL_TT1/* 通过 GART/GTT 映射的系统内存,GPU 可访问 */#defineTTM_PL_VRAM2/* GPU 显存,性能最高 */驱动可以扩展定义自己的域类型(如 AMDGPU 定义了AMDGPU_PL_GDS、AMDGPU_PL_PREEMPT等)。
3. Placement 标志 (Flags)
3.1 基本标志
| 标志 | 含义 |
|---|---|
TTM_PL_FLAG_CONTIGUOUS | 要求在该域中连续分配 |
TTM_PL_FLAG_TEMPORARY | 临时放置(multi-hop 中转用) |
3.2 DESIRED / FALLBACK 标志与两轮分配
TTM_PL_FLAG_DESIRED和TTM_PL_FLAG_FALLBACK是 TTM 实现"优雅降级"的关键:
structttm_placeplacements[]={{.mem_type=TTM_PL_VRAM,.flags=TTM_PL_FLAG_DESIRED},/* 首选 */{.mem_type=TTM_PL_TT,.flags=TTM_PL_FLAG_FALLBACK},/* 后备 */};ttm_bo_mem_space()对每个 placement 执行两轮尝试:
| 轮次 | force_space | 跳过的标志 | 行为 |
|---|---|---|---|
| 第 1 轮 | false | TTM_PL_FLAG_FALLBACK | 只尝试 DESIRED 域,不驱逐 |
| 第 2 轮 | true | TTM_PL_FLAG_DESIRED | 只尝试 FALLBACK 域,允许驱逐 |
这意味着:
- 第 1 轮:只在首选域中尝试分配(不驱逐别人),如果有空闲空间就直接成功
- 第 2 轮:首选域分配失败后,转向后备域,此时允许驱逐已有 BO 来腾出空间
没有标记 DESIRED 或 FALLBACK 的域,两轮都会尝试。
4. Placement 的使用场景
4.1 BO 创建时 – 初始放置
驱动在创建 BO 时构造ttm_placement,告诉 TTM 这个 BO 应该放在哪里:
驱动创建 BO: -> 构造 ttm_placement (如: 优先 VRAM, 后备 GTT) -> ttm_bo_init_reserved() -> ttm_bo_validate(placement) -> ttm_bo_alloc_resource() -- 按 placement 顺序尝试分配4.2 BO 迁移/重新放置时 – validate
当 BO 需要迁移到新的域时(如 CS 提交时需要 BO 在 GPU 可访问域),驱动构造新的ttm_placement再次调用ttm_bo_validate():
Command Submission: -> 构造新 placement (要求 VRAM 或 GTT) -> ttm_bo_validate(new_placement) -> BO 不在合适位置? -> 分配新资源 + 搬迁4.3 Eviction 时 – 降级放置
当 BO 被驱逐时,驱动通过evict_flags()回调返回一个降级 placement,告诉 TTM 这个被踢出的 BO 应该去哪里:
BO 被驱逐: -> 驱动回调 evict_flags(bo, &placement) -> 返回降级 placement (如: VRAM -> GTT, GTT -> SYSTEM) -> ttm_bo_evict() 按此 placement 搬迁 BO这个降级链可以级联:VRAM 中的 BO 被踢到 GTT,如果 GTT 也满了,GTT 中的某个 BO 又会被踢到 SYSTEM。
5. Placement 与 TTM 资源管理器的关系
ttm_device | +-- man_drv[TTM_PL_SYSTEM] --> system resource manager +-- man_drv[TTM_PL_TT] --> GTT resource manager (驱动实现) +-- man_drv[TTM_PL_VRAM] --> VRAM resource manager (驱动实现) +-- man_drv[...] --> 驱动自定义域 ttm_placement { placement[] } | +-- placement[0]: { mem_type = TTM_PL_VRAM } --> 查找 man_drv[VRAM] +-- placement[1]: { mem_type = TTM_PL_TT } --> 查找 man_drv[TT]ttm_bo_alloc_resource()遍历placement[]时,通过ttm_manager_type(bdev, place->mem_type)定位对应的资源管理器,然后调用该管理器的ttm_resource_alloc()进行分配。
6. AMD 驱动中的 Placement 域
AMDGPU 在 TTM 标准域之上扩展了多个自定义域,通过amdgpu_bo_placement_from_domain()将用户态的 domain flags 转化为ttm_placement:
| 用户态 Domain Flag | TTM mem_type | 含义 |
|---|---|---|
AMDGPU_GEM_DOMAIN_VRAM | TTM_PL_VRAM | GPU 显存,性能最高 |
AMDGPU_GEM_DOMAIN_GTT | TTM_PL_TT | 通过 GART 映射的系统内存 |
AMDGPU_GEM_DOMAIN_CPU | TTM_PL_SYSTEM | 纯系统内存,GPU 不可直接访问 |
AMDGPU_GEM_DOMAIN_GDS | AMDGPU_PL_GDS | 片上 Global Data Share |
AMDGPU_GEM_DOMAIN_GWS | AMDGPU_PL_GWS | 片上 Global Wave Sync |
AMDGPU_GEM_DOMAIN_OA | AMDGPU_PL_OA | 片上 Ordered Append |
| (内部) | AMDGPU_PL_PREEMPT | 可抢占 BO (KFD 用) |
| (内部) | AMDGPU_PL_DOORBELL | Doorbell 寄存器映射 |
7. 小结
ttm_placement是 TTM 多内存域管理的中枢调度指令。TTM 框架本身不决定 BO 放在哪里——它只是一个执行者;真正做决策的是驱动通过ttm_placement下达的指令。可以说:
没有
ttm_placement,TTM 的多域管理、eviction、迁移都无从谈起。
它在 TTM 中扮演三重角色:
- 分配指令:BO 创建时,
ttm_placement告诉 TTM “按这个优先级去这些域里找空间” - 迁移指令:
ttm_bo_validate()时,新的ttm_placement告诉 TTM “把 BO 搬到这些域” - 降级指令:eviction 时,
evict_flags()返回的ttm_placement告诉 TTM “被踢的 BO 该去哪里”
| 要点 | 内容 |
|---|---|
| 本质 | BO 对 TTM 的内存域偏好声明,服务于"多内存域统一管理"目标 |
| 核心作用 | TTM 所有涉及"BO 放在哪"的决策,都由ttm_placement驱动 |
| 结构 | ttm_placement包含有序ttm_place[]数组 |
| 两轮机制 | DESIRED (首选) / FALLBACK (后备) 标志实现优雅降级 |
| 三个场景 | 创建 (初始放置)、validate (迁移)、eviction (降级) |
| 驱动扩展 | 驱动可自定义域类型和降级策略 |