本系列在前文深入分析了drm的基础上,深入分析 Linux 内核 DRM 子系统中的 TTM (Translation Table Maps) 框架核心组件 ttm_tt,结合 AMD GPU 驱动实现,全面讲解其原理、实现和应用。
📚 文档结构
第一篇:概述与核心原理
主要内容:
- TTM 框架概述与 ttm_tt 定位
- 核心数据结构详解
struct ttm_tt基础结构struct ttm_dma_ttDMA 扩展struct amdgpu_ttm_ttAMD 扩展
- 页面标志位与缓存状态
- 后端操作接口设计
- 生命周期状态机
- 地址空间映射机制
- 关键特性(延迟分配、Swap 支持)
关键概念:
- GTT (Graphics Translation Table)
- 三态状态机:unpopulated → unbound → bound
- 缓存策略:cached/wc/uncached
- DMA 映射与 GART 绑定
第二篇:AMD 驱动实现详解
主要内容:
- AMD 特有扩展设计
- 创建与初始化流程
- 页面填充(Populate)三种场景
- 普通内存分配
- Userptr 零拷贝
- DMA-BUF 导入
- GART 绑定详细实现
- PTE 标志计算机制
- 解绑与资源释放
- HMM 集成实现
- 完整生命周期示例
核心代码分析:
amdgpu_ttm_tt_create()- 对象创建amdgpu_ttm_tt_populate()- 页面分配amdgpu_ttm_backend_bind()- GART 绑定amdgpu_ttm_tt_pin_userptr()- Userptr 处理
第三篇:应用场景与最佳实践
主要内容:
- 五大典型应用场景
- 渲染缓冲溢出管理
- 纹理上传暂存
- Compute Kernel 零拷贝输入
- 视频解码 DMA-BUF 共享
- Swap 超额分配
- 缓存策略选择指南
- 性能优化技巧
- 减少 DMA 映射开销
- 大页优化
- Prefault 策略
- 对象复用
- 调试方法与工具
- 常见问题与解决方案
实用决策表:
- 场景 → 方案 → 配置映射
- 缓存模式性能对比
- 优化技巧清单
🎯 快速导航
按问题查找
| 问题 | 章节 |
|---|---|
| ttm_tt 是什么? | 第一篇 §1 |
| 如何创建 ttm_tt? | 第二篇 §2 |
| Userptr 如何实现? | 第二篇 §8 |
| 什么场景用 GTT? | 第三篇 §1.1, §2.1 |
| 如何选择缓存策略? | 第三篇 §3 |
| 性能优化方法? | 第三篇 §4 |
| 调试 "bind failed"? | 第三篇 §5,§6 |
| DMA-BUF 如何集成? | 第二篇 §3.2(2), 第三篇 §2.4 |
🔑 核心概念速查
关键数据结构
c
struct ttm_tt {
struct page **pages; // 页面数组
enum { unpopulated, unbound, bound } state; // 状态
enum ttm_caching_state caching_state; // 缓存策略
};
生命周期
创建 → 填充(populate) → 绑定(bind) → 使用 → 解绑(unbind) → 释放(unpopulate) → 销毁
三种内存模式
| 模式 | CPU 性能 | GPU 性能 | 用途 |
|---|---|---|---|
| cached | 高 | 中 | CPU 密集 |
| wc | 中 | 高 | GPU 密集 |
| uncached | 低 | 高 | 强一致性 |
🛠️ 代码示例索引
| 示例 | 文档位置 |
|---|---|
| 创建 GTT Buffer | 第三篇 §2.1 |
| Staging 上传 | 第三篇 §2.2 |
| Userptr 使用 | 第三篇 §2.3 |
| DMA-BUF 导入 | 第三篇 §2.4 |
| GART 绑定流程 | 第二篇 §4 |
| HMM 集成 | 第二篇 §8 |
| 完整生命周期 | 第二篇 §9 |
✅ 关键要点总结
设计理念
- 延迟分配:按需创建,节省资源
- 统一抽象:支持多种内存源(normal/userptr/dma-buf)
- 灵活绑定:动态映射 GPU 地址空间
- 透明 Swap:支持内存超额分配
最佳实践
- ✅ 创建时确定缓存策略
- ✅ 使用 write-combined 优化上传
- ✅ Userptr 用于零拷贝
- ✅ 批量操作减少开销
- ✅ 及时释放不用的 BO
常见陷阱
- ❌ 频繁修改缓存属性
- ❌ Userptr 生命周期管理不当
- ❌ 忽略 DMA 映射开销
- ❌ GART 地址空间耗尽
- ❌ 过度依赖 Swap 导致抖动
后文还在自我审核中,修订后发布。