DRM Buddy Allocator 技术学习文档系列目录

本系列文档旨在帮助新手系统学习DRM Buddy内存分配器及其在AMDGPU驱动中的应用。


第一部分:基础篇 🟢

适合完全新手,建立基础概念

01-什么是Buddy分配器

  • 1.1 内存分配器的基本需求
  • 1.2 传统分配器的局限性
  • 1.3 Buddy算法的核心思想
  • 1.4 二叉树与伙伴关系
  • 1.5 DRM Buddy的特点和优势

核心概念:

  • 二进制分块
  • 伙伴对(Buddy Pair)
  • 分裂与合并
  • 内存碎片

02-GPU显存管理基础

  • 2.1 GPU显存架构
  • 2.2 VRAM vs 系统内存
  • 2.3 显存分配的特殊需求
    • 大块连续内存
    • 对齐要求
    • 范围限制
  • 2.4 TTM (Translation Table Manager) 简介
  • 2.5 Buddy在显存管理中的角色

关键术语:

  • VRAM (Video RAM)
  • GTT (Graphics Translation Table)
  • 内存域 (Memory Domain)
  • 页面大小和对齐

03-DRM子系统与AMDGPU架构

  • 3.1 DRM核心架构
  • 3.2 DRM内存管理框架
  • 3.3 AMDGPU驱动架构概览
  • 3.4 AMDGPU VRAM管理器
  • 3.5 Buddy分配器在整体架构中的位置

第二部分:数据结构篇 🟡

理解代码组织,掌握核心数据结构

04-核心数据结构详解

  • 4.1 struct drm_buddy - 分配器主结构
    • chunk_size - 最小分配单元
    • max_order - 最大阶数
    • size - 总大小
    • avail - 可用空间
    • roots[] - 根块数组
  • 4.2 struct drm_buddy_block - 内存块表示
    • header - 状态和阶数
    • offset - 块偏移
    • link - 链表节点
    • left/right - 二叉树指针
  • 4.3 块状态标志
    • DRM_BUDDY_ALLOCATED
    • DRM_BUDDY_FREE
    • DRM_BUDDY_SPLIT
    • DRM_BUDDY_CLEAR
  • 4.4 数据结构关系图

位置 : include/drm/drm_buddy.h

05-AMDGPU中的VRAM管理器

  • 5.1 struct amdgpu_vram_mgr 结构
  • 5.2 与DRM Buddy的集成
  • 5.3 分配统计和跟踪
  • 5.4 VRAM使用率监控

第三部分:核心算法篇 🟡🔴

深入实现细节,理解关键算法

06-Buddy分配算法

  • 6.1 分配请求处理流程
  • 6.2 查找合适大小的块
  • 6.3 块的分裂(Split)过程
  • 6.4 order计算和对齐处理
  • 6.5 分配算法的时间复杂度

核心函数:

  • drm_buddy_alloc_blocks() - 主分配入口
  • __drm_buddy_alloc_range() - 范围分配
  • split_block() - 分裂块
  • alloc_from_freelist() - 从空闲列表分配

07-Buddy释放与合并算法

  • 7.1 释放流程概述
  • 7.2 查找伙伴块
  • 7.3 合并条件判断
  • 7.4 递归合并过程
  • 7.5 合并优化技术

核心函数:

  • drm_buddy_free_block() - 释放单个块
  • drm_buddy_free_list() - 批量释放
  • __drm_buddy_free() - 内部释放逻辑
  • merge_buddies() - 合并伙伴

08-块的分裂与重组

  • 8.1 分裂的触发条件
  • 8.2 二叉树构建过程
  • 8.3 Left/Right子块关系
  • 8.4 分裂的递归实现
  • 8.5 分裂深度限制

09-对齐和范围限制

  • 9.1 对齐需求的来源
    • GPU硬件要求
    • 页表映射需求
    • DMA传输优化
  • 9.2 对齐实现机制
  • 9.3 范围分配(Range Allocation)
  • 9.4 起始地址限制
  • 9.5 对齐和范围的组合处理

核心函数:

  • drm_buddy_alloc_blocks() - min_block_size 参数
  • __drm_buddy_alloc_range() - 范围分配
  • align_start_offset() - 对齐计算

10-空闲列表管理

  • 10.1 每个Order的空闲列表
  • 10.2 空闲块的组织
  • 10.3 快速查找策略
  • 10.4 列表操作的原子性
  • 10.5 空闲统计维护

数据结构:

c 复制代码
struct drm_buddy {
    struct list_head free_list[DRM_BUDDY_MAX_ORDER + 1];
    // 每个 order 一个链表
};

第四部分:AMDGPU集成篇 🟡🔴

理解在实际驱动中的应用

11-AMDGPU-VRAM分配流程

  • 11.1 VRAM分配请求来源
    • Buffer Object 创建
    • 显存分配 ioctl
    • 内核内部分配
  • 11.2 AMDGPU VRAM Manager 初始化
  • 11.3 从TTM到Buddy的调用链
  • 11.4 BO创建时的内存分配
  • 11.5 分配失败处理

12-连续与非连续内存分配

  • 12.1 连续分配需求
    • Display buffer
    • Framebuffer
    • 某些DMA操作
  • 12.2 非连续分配的优势
  • 12.3 Buddy支持的分配模式
  • 12.4 DRM_BUDDY_CONTIGUOUS 标志
  • 12.5 多块分配策略

13-内存碎片与整理

  • 13.1 碎片产生的原因
    • 外部碎片
    • 内部碎片
  • 13.2 碎片的影响
  • 13.3 Buddy算法的碎片特性
  • 13.4 碎片整理策略
  • 13.5 VRAM回收机制

14-Clear-on-Free机制

  • 14.1 为什么需要清零
    • 安全性考虑
    • 数据残留风险
  • 14.2 DRM_BUDDY_CLEAR 标志
  • 14.3 清零时机选择
  • 14.4 性能影响分析
  • 14.5 延迟清零优化

第五部分:高级特性篇 🔴

掌握高级功能和优化技术

15-性能优化与监控

  • 15.1 分配性能分析
  • 15.2 缓存和预分配
  • 15.3 分配路径优化
  • 15.4 内存使用统计
  • 15.5 debugfs监控接口

性能指标:

  • 分配成功率
  • 平均分配时间
  • 碎片率
  • 空闲块分布

Debugfs接口:

bash 复制代码
cat /sys/kernel/debug/dri/0/amdgpu_vram_mm
cat /sys/kernel/debug/dri/0/amdgpu_gem_info

16-多显存域支持

  • 16.1 可见显存 vs 不可见显存
  • 16.2 不同显存域的管理
  • 16.3 跨域分配策略
  • 16.4 Resizable BAR 影响

17-错误处理与恢复

  • 17.1 分配失败场景
  • 17.2 内存泄漏检测
  • 17.3 块状态异常处理
  • 17.4 VRAM损坏应对
  • 17.5 调试和诊断技巧

常见错误:

  • ENOMEM - 内存不足
  • ENOSPC - 连续块不足
  • 块状态不一致
  • 伙伴关系错误

18-与其他分配器的对比

  • 18.1 Buddy vs Slab
  • 18.2 Buddy vs Bitmap
  • 18.3 Buddy vs CMA
  • 18.4 选择合适的分配器
  • 18.5 混合使用策略

19-调试技巧与工具

  • 19.1 启用调试输出
  • 19.2 内存泄漏追踪
  • 19.3 可视化工具
  • 19.4 常见问题排查
  • 19.5 单元测试

学习路径建议

🎯 初学者路径 (2-3周)

  1. 第一部分:基础篇 (01-03) → 理解概念和背景
  2. 第二部分:数据结构篇 (04-05) → 掌握核心结构
  3. 第三部分:核心算法篇 (06-10) → 理解分配释放算法

🚀 有经验者路径 (1周)

  1. 快速浏览 01-03,重点看 03
  2. 精读 04-05,理解数据结构
  3. 重点学习 06-07(分配和释放)
  4. 按需选读 11-19 的具体应用

🔍 问题驱动路径

  • VRAM分配失败: 重点看 06、11、13、17 章
  • 性能优化: 重点看 15、16 章
  • 调试排查: 重点看 17、19 章
  • 驱动开发: 重点看 11-14 章

代码阅读顺序建议

第一轮:理解核心

bash 复制代码
# 1. 数据结构定义
include/drm/drm_buddy.h           - 完整阅读

# 2. 核心算法实现
drivers/gpu/drm/drm_buddy.c       - 分模块阅读
  - 行1-100:    初始化和清理
  - 行100-400:  分配算法
  - 行400-600:  释放和合并
  - 行600-800:  辅助函数

# 3. AMDGPU集成
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
  - 重点: amdgpu_vram_mgr_new()
  - 重点: amdgpu_vram_mgr_del()

第二轮:理解流程

跟踪关键流程的完整调用链:

  1. VRAM分配 : amdgpu_gem_create()ttm_bo_init()amdgpu_vram_mgr_new()drm_buddy_alloc_blocks()
  2. 块分裂 : drm_buddy_alloc_blocks()alloc_from_freelist()split_block()
  3. 块合并 : drm_buddy_free_block()__drm_buddy_free()merge_buddies()

第三轮:深入细节

专题深入研究:

  1. 对齐机制: order计算、min_block_size、对齐算法
  2. 性能优化: 空闲列表管理、批量操作、缓存策略
  3. 错误处理: 各种失败场景、状态检查、恢复机制

快速参考

核心数据结构速查

结构体 文件 关键字段 作用
drm_buddy drm_buddy.h chunk_size, max_order, roots[] 分配器主结构
drm_buddy_block drm_buddy.h header, offset, left/right 内存块节点
amdgpu_vram_mgr amdgpu_vram_mgr.c mm, usage, lock VRAM管理器

关键宏定义

c 复制代码
#define DRM_BUDDY_MAX_ORDER          63    // 最大阶数
#define DRM_BUDDY_ALLOCATED         (1 << 0)  // 已分配
#define DRM_BUDDY_FREE              (1 << 1)  // 空闲
#define DRM_BUDDY_SPLIT             (1 << 2)  // 已分裂
#define DRM_BUDDY_CLEAR             (1 << 3)  // 需清零

核心API

c 复制代码
// 初始化和清理
int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size);
void drm_buddy_fini(struct drm_buddy *mm);

// 分配和释放
int drm_buddy_alloc_blocks(struct drm_buddy *mm, u64 start, u64 end,
                           u64 size, u64 min_block_size,
                           struct list_head *blocks, unsigned long flags);
void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
void drm_buddy_free_list(struct drm_buddy *mm, struct list_head *objects);

// 查询和统计
u64 drm_buddy_avail_size(struct drm_buddy *mm);
void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p);

术语速查

术语 全称/解释 说明
Buddy Buddy Allocator 伙伴分配器
Order - 块的大小等级 (2^order pages)
Block Memory Block 内存块,Buddy的基本单元
Split Block Split 块分裂,将大块分成两个小块
Merge Buddy Merge 合并伙伴块
Chunk Minimum Chunk 最小分配单元
VRAM Video RAM 显存
GTT Graphics Translation Table 图形地址转换表
TTM Translation Table Maps 转换表管理器
BO Buffer Object 缓冲对象
BAR Base Address Register 基地址寄存器
DMA Direct Memory Access 直接内存访问

实验环境搭建

内核模块编译

bash 复制代码
# 编译 DRM buddy 模块
cd linux/drivers/gpu/drm
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

# 加载模块
sudo insmod drm_buddy.ko

用户态测试

bash 复制代码
# 查看 VRAM 状态
cat /sys/kernel/debug/dri/0/amdgpu_vram_mm

# 测试程序示例
./test_vram_alloc 1024  # 分配 1024MB VRAM

下一步 : 👉 开始学习 01-什么是Buddy分配器

相关推荐
DeeplyMind2 天前
第11章:AMDGPU-VRAM分配流程
drm_buddy
DeeplyMind17 天前
06 - Buddy分配算法
drm_buddy
DeeplyMind18 天前
07 - Buddy释放与合并算法
drm_buddy
DeeplyMind21 天前
05 - AMDGPU中的VRAM管理器
drm·amdgpu·drm_buddy·ttm
DeeplyMind25 天前
04 - 核心数据结构详解
drm·drm_buddy·vram
DeeplyMind1 个月前
03 - DRM子系统与AMDGPU架构
drm·drm_buddy·vram分配
DeeplyMind3 个月前
Linux DRM 内存管理子系统的概念关系理解:gem、ttm、drm_buddy
drm·tm·drm_buddy