Linux DRM 内存管理子系统的概念关系理解:gem、ttm、drm_buddy

概述

在 Linux 直接渲染管理器子系统中,drm_buddy、GEM 和 TTM 是三个重要的内存管理组件。它们并不是互斥的关系,而是服务于内存管理堆栈的不同层级,协同工作以实现高效的 GPU 内存管理。

核心组件

1. GEM

定位:用户空间 API 和缓冲区句柄管理

主要职责
  • 为用户空间应用程序(如 Mesa/OpenGL)提供标准的缓冲区管理 API
  • 通过 ioctl 接口管理内存句柄(handles)的创建、映射和共享
  • 处理缓冲区对象的引用计数和生命周期管理
设计特点
  • 简洁性:最初为统一内存架构(UMA)系统设计,避免复杂的内存迁移
  • 硬件目标:主要面向集成显卡,GPU 共享系统主内存
  • 用户友好:提供简单直观的用户空间接口
使用范围

几乎所有现代 DRM 驱动程序都使用 GEM 作为用户空间接口标准。


2. TTM (Translation Table Manager)

定位:高层缓冲区放置与迁移管理器

主要职责
  • 管理缓冲区对象的完整生命周期
  • 决定缓冲区应该存放的位置(VRAM、GTT 或系统内存)
  • 处理内存域之间的缓冲区迁移和交换
  • 实现复杂的内存驱逐策略
设计特点
  • 复杂性高:专为具有多种内存类型的独立显卡设计
  • 硬件目标:独立显卡,管理专用 VRAM
  • 功能全面:处理系统 RAM 和 VRAM 之间的所有复杂操作
使用范围
  • AMD 驱动程序(amdgpu)
  • NVIDIA 开源驱动(Nouveau)
  • VMware 虚拟显卡驱动
典型工作流程
复制代码
用户请求 → TTM 评估 → 选择内存域 → 必要时驱逐旧缓冲区 → 调用底层分配器

3. drm_buddy

定位:底层物理块分配器

主要职责
  • 管理内存池(如 VRAM)的内部物理布局
  • 使用 buddy 算法进行高效的页级别分配
  • 减少内存碎片,提高分配效率
  • 作为 TTM 或其他管理器的后端分配引擎
设计特点
  • 模块化:可以被不同驱动程序插入使用
  • 硬件目标:现代独立显卡的 VRAM 管理
  • 专注性:专注于 buddy 分配算法的实现
使用范围
  • Intel 驱动程序(i915/Xe)
  • AMD 驱动程序(amdgpu)作为 TTM 的底层分配器
Buddy 算法优势
  • 快速分配和释放
  • 自动合并相邻空闲块
  • 减少外部碎片
  • 支持不同大小的内存请求

三者关系详解

drm_buddy 与 TTM 的关系

虽然 TTM 是处理复杂操作的高层管理器,drm_buddy 是其底层分配后端:

方面 TTM drm_buddy
作用域 管理缓冲区对象生命周期,决定存放位置 管理内存池内部的物理块分配
层级 高层策略管理 底层分配算法
职责 WHERE(在哪里分配) HOW(如何分配物理页)
复杂度 高,处理迁移、驱逐等复杂逻辑 相对简单,专注分配算法

协作示例

复制代码
amdgpu 驱动:
  TTM (决策层) → 决定使用 VRAM
       ↓
  drm_buddy (执行层) → 在 VRAM 中找到具体的物理页

drm_buddy 与 GEM 的关系

GEM 提供用户空间接口,drm_buddy 是内核内部工具:

方面 GEM drm_buddy
接口层 用户空间 API(ioctl) 内核内部接口
可见性 对应用程序可见 应用程序不可见
抽象级别 高层缓冲区抽象 底层物理内存管理
交互方式 应用程序直接调用 仅被内核驱动使用

协作示例

复制代码
用户空间应用:
  调用 GEM ioctl (创建缓冲区)
       ↓
  内核驱动接收请求
       ↓
  调用 drm_buddy 分配物理内存
       ↓
  返回 GEM 句柄给用户空间

完整对比表

特性 GEM TTM drm_buddy
主要角色 用户空间 API & 句柄管理 高层缓冲区放置 & 迁移 底层物理块分配
硬件目标 UMA 系统(集成显卡) 独立显卡(专用 VRAM) 独立显卡(VRAM 管理)
复杂度 低:简单接口,避免复杂迁移 高:处理所有内存类型和迁移 中:模块化,专注 buddy 算法
层级 用户空间接口层 内核策略层 内核执行层
使用者 几乎所有现代驱动 AMD, Nouveau, VMware Intel (i915/Xe), AMD (amdgpu)
内存类型 主要是系统内存 VRAM, GTT, 系统内存 主要是 VRAM
用户可见性 可见(通过 ioctl) 不可见 不可见

工作流程示例

场景:应用程序请求创建一个 GPU 缓冲区

复制代码
1. 用户空间应用
   └─> 调用 GEM API: "我需要一个 16MB 的缓冲区"
        │
2. GEM 层(内核)
   └─> 创建 GEM 对象,分配句柄
        │
3. TTM 层(如果驱动使用 TTM)
   └─> 决策:"这个缓冲区应该放入 VRAM"
   └─> 检查 VRAM 空间
   └─> 如果需要,驱逐旧缓冲区
        │
4. drm_buddy 层
   └─> 在 VRAM 中执行 buddy 分配
   └─> 找到连续的物理页块
   └─> 返回物理地址
        │
5. 返回路径
   └─> TTM 更新页表
   └─> GEM 完成对象初始化
   └─> 返回句柄给用户空间

驱动程序实现模式

模式 1:GEM + drm_buddy(简单型)

适用于:现代集成显卡或简单独立显卡

复制代码
Intel i915/Xe:
  - GEM 提供用户接口
  - drm_buddy 管理 VRAM 分配
  - 无需 TTM 的复杂迁移逻辑

模式 2:GEM + TTM + drm_buddy(完整型)

适用于:复杂的独立显卡

复制代码
AMD amdgpu:
  - GEM 提供用户接口
  - TTM 处理内存放置和迁移
  - drm_buddy 作为 TTM 的底层分配器

模式 3:仅 GEM(传统型)

适用于:简单的 UMA 系统

复制代码
部分集成显卡驱动:
  - 仅使用 GEM
  - 直接使用系统内存
  - 无需 VRAM 管理

关键概念总结

一句话总结

GEM 告诉内核 "我需要一个缓冲区"
TTM 决定 "这个缓冲区应该放入 VRAM"
drm_buddy 在 VRAM 中找到确切的物理页来存放它

层次关系

复制代码
┌─────────────────────────────────────┐
│   用户空间应用(OpenGL/Vulkan)        │
└──────────────┬──────────────────────┘
               │ ioctl
┌──────────────▼──────────────────────┐
│   GEM (用户空间接口层)                │
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│   TTM (策略与迁移层) - 可选            │
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│   drm_buddy (物理分配层)              │
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│   物理 VRAM / 系统内存                │
└─────────────────────────────────────┘

实际应用场景

场景 1:游戏加载大纹理

  1. GEM:应用请求创建纹理缓冲区
  2. TTM:判断纹理应该在 VRAM 中以获得最佳性能
  3. drm_buddy:在 VRAM 中分配连续的物理页
  4. 结果:GPU 可以高速访问纹理数据

场景 2:内存压力下的缓冲区驱逐

  1. TTM:检测到 VRAM 不足
  2. TTM:选择不常用的缓冲区驱逐到系统内存
  3. drm_buddy:释放 VRAM 物理页
  4. drm_buddy:为新请求分配刚释放的空间

场景 3:多进程共享缓冲区

  1. GEM:进程 A 创建缓冲区,获得句柄
  2. GEM:通过 DMA-BUF 导出句柄
  3. GEM:进程 B 导入句柄,共享同一物理内存
  4. 底层:drm_buddy 分配的物理页被两个进程共享

参考资源


结论

DRM 内存管理子系统通过三个层次的组件实现了灵活高效的 GPU 内存管理:

  • GEM 提供统一的用户空间接口
  • TTM 处理复杂的内存策略和迁移
  • drm_buddy 提供高效的物理内存分配

这种分层设计使得驱动程序可以根据硬件特性选择合适的组件组合,既保证了接口的统一性,又提供了实现的灵活性。

相关推荐
DeeplyMind5 天前
第7章:DRM内核调试技术:7.1 DRM DebugFS的使用
linux·驱动开发·drm·debugfs·drm debugfs
DeeplyMind1 个月前
linux drm子系统技术分析目录表
linux·驱动开发·drm
Micro麦可乐1 个月前
前端真的能防录屏?EME(加密媒体扩展) DRM 反录屏原理 + 实战代码
前端·媒体·eme·drm·前端防盗录
JasonSJX2 个月前
海海软件成为微软 PlayReady DRM 官方合作伙伴
microsoft·drm·视频加密·playready·数字版权保护
赋能大师兄2 个月前
手机终端传输模式深入介绍
手机终端·传输模式·tm
DeeplyMind2 个月前
linux drm子系统专栏介绍
linux·驱动开发·ai·drm·amdgpu·kfd
DeeplyMind4 个月前
AMD KFD的BO设计分析系列3-4:Linux DRM GEM mmap 与 drm_vma_offset_node 机制详解
linux·drm·opengl驱动·drm_gem_object
林政硕(Cohen0415)9 个月前
Linux驱动开发进阶(七)- DRM驱动程序设计
linux·驱动开发·drm
songze_lee1 年前
openharmony系统移植之显示驱动框架从framebuffer升级为drm(linux-5.10)
linux·openharmony·drm