1. 概述
AMDGPU_GEM_CREATE_VRAM_CLEARED 是 AMDGPU 驱动中用于 GEM 对象创建的一个标志位。当用户空间或内核分配 VRAM buffer 时设置此标志,驱动会确保分配的显存内容被清零。
/* Flag that the memory should be in VRAM and cleared */
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
2. 功能目的
- 安全性保障:防止新分配的 buffer 包含前一用户的残留数据,避免信息泄露
- 初始化一致性:确保 buffer 内容从已知状态(全零)开始
- 配合
AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE:后者在释放时擦除敏感数据
3. 实现流程
3.1 入口检查 (amdgpu_bo_create)
在 amdgpu_object.c 的 amdgpu_bo_create() 函数中:
if (bp->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
bo->tbo.resource->mem_type == TTM_PL_VRAM) {
struct dma_fence *fence;
r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
bo, bo->tbo.base.resv, &fence,
true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER);
// ...
if (fence) {
dma_resv_add_fence(bo->tbo.base.resv, fence,
DMA_RESV_USAGE_KERNEL);
dma_fence_put(fence);
}
}
关键点:
- 仅当 buffer 实际分配在 VRAM 时才执行清零
- 使用 fence 机制确保清零操作完成后才能使用 buffer
3.2 缓冲区清零 (amdgpu_ttm_clear_buffer)
int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct amdgpu_bo *bo,
struct dma_resv *resv,
struct dma_fence **out_fence,
bool consider_clear_status,
u64 k_job_id)
实现要点:
- 使用
amdgpu_res_cursor遍历 buffer 的所有内存区域 - 每次最多处理 256MB,避免 GPU 超时
- 支持跳过已标记为已清零的区域(
consider_clear_status)
while (dst.remaining) {
/* Never fill more than 256MiB at once to avoid timeouts */
cur_size = min(dst.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(entity, &bo->tbo, ...);
r = amdgpu_ttm_fill_mem(adev, entity, 0, to, cur_size, ...);
// ...
}
3.3 SDMA 填充 (amdgpu_ttm_fill_mem)
最终通过 SDMA (System DMA) 引擎执行硬件加速的内存填充:
static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
uint32_t src_data, // 填充值,此处为 0
uint64_t dst_addr, // 目标地址
uint32_t byte_count, // 字节数
...)
{
for (i = 0; i < num_loops; i++) {
amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data, dst_addr,
cur_size);
// ...
}
}
4. 架构图
用户空间/内核
│
▼ AMDGPU_GEM_CREATE_VRAM_CLEARED
┌──────────────────────┐
│ amdgpu_bo_create() │
└──────────┬───────────┘
│ mem_type == TTM_PL_VRAM?
▼
┌────────────────────────────┐
│ amdgpu_ttm_clear_buffer() │
│ 遍历所有内存区域 │
│ 每块 ≤ 256MB │
└──────────┬─────────────────┘
│
▼
┌────────────────────────────┐
│ amdgpu_ttm_fill_mem() │
│ 构建 SDMA fill 命令 │
└──────────┬─────────────────┘
│
▼
┌────────────────────────────┐
│ SDMA Engine (GPU) │
│ 硬件加速清零 │
└────────────────────────────┘
5. 相关标志
| 标志 | 说明 |
|---|---|
AMDGPU_GEM_CREATE_VRAM_CLEARED | 分配时清零 |
AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE | 释放时擦除敏感数据 |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | 分配连续 VRAM |
6. 性能考量
- 清零操作由 GPU SDMA 引擎异步执行,不阻塞 CPU
- 通过 fence 同步,用户在实际使用 buffer 前等待完成
- 分块处理(256MB)避免单次操作超时
7. 使用场景
- 安全敏感应用:加密密钥、用户数据等
- 图形渲染:避免屏幕出现"花屏"(残留纹理数据)
- 计算负载:确保累加器等从零开始
8. 一句话总结
AMDGPU_GEM_CREATE_VRAM_CLEARED 在分配 VRAM 时通过 SDMA 引擎异步填零(amdgpu_ttm_fill_mem 提交 GPU job),并用 fence 同步确保使用前完成,避免信息泄露。

2182

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



