跳到主要内容 AMDGPU 驱动架构概览 | 极客日志
C AI
AMDGPU 驱动架构概览 AMDGPU 驱动由图形驱动 AMDGPU 和计算驱动 KFD 组成,SVM 功能主要在 KFD 中实现。文章阐述了驱动的层次结构、关键组件及 SVM 在其中的位置。KFD 负责进程管理、设备管理及 SVM 逻辑,通过字符设备接口暴露给用户空间。TTM 框架管理 VRAM 和 GTT 内存,Buffer Object 用于显存分配。GART 表允许 GPU 访问系统内存,是页面迁移的关键桥梁。SVM 利用 TTM 管理显存,结合 GART 实现 CPU 与 GPU 间的统一地址空间管理。理解这些架构有助于深入 SVM 具体实现。
PentesterX 发布于 2026/2/7 0 浏览难度 : 🟡 进阶
预计学习时间 : 1-1.5 小时
前置知识 : Linux 驱动基础、前两章内容
📋 概述 在深入 SVM 实现细节之前,我们需要理解 AMDGPU 驱动的整体架构。AMDGPU 是一个复杂的驱动系统,包含显卡驱动(AMDGPU)和计算驱动(KFD)两大部分。SVM 功能主要在 KFD 中实现,但与 AMDGPU 的其他组件紧密协作。
本章将介绍驱动的层次结构、关键组件以及 SVM 在其中的位置。
3.1 AMDGPU 驱动整体架构 ┌─────────────────────────────────────────┐
│ 用户空间应用 │
│ [OpenGL] [Vulkan] [OpenCL] [HIP] │
└─────────────────────────────────────────┘
↓ ↓ ↓
┌────────┐ ┌─────────┐ ┌─────────┐
│Mesa/驱动│ │libdrm │ │ROCm RT │
└────────┘ └─────────┘ └─────────┘
↓ ↓ ======================================
内核空间 ======================================
↓ ↓
┌──────────┐ ┌──────────┐
│ AMDGPU │ │ KFD │
│ (DRM) │ ←──────→ │ (Compute)│
│ 图形驱动 │ │ 计算驱动 │
└──────────┘ └──────────┘
↓ ↓
┌────────────────────────────┐
│ GPU 硬件 │
│ [GFX] [Compute] [SDMA] │
└────────────────────────────┘
AMDGPU 驱动
位置 : drivers/gpu/drm/amd/amdgpu/
作用 :
图形渲染支持
显示输出(DisplayPort, HDMI 等)
GPU 内存管理(TTM)
GPU 电源管理
基础硬件抽象
KFD 驱动(Kernel Fusion Driver)
位置 : drivers/gpu/drm/amd/amdkfd/
作用 :
HSA 支持(Heterogeneous System Architecture)
计算队列管理
进程管理
SVM 实现 ← 我们关注的重点
调试支持
目录结构 drivers/gpu/drm/amd/
├── amdgpu/
│ ├── amdgpu_vm.c
│ ├── amdgpu_ttm.c
│ ├── amdgpu_device.c
│ └── ...
├── amdkfd/
│ ├── kfd_module.c
│ ├── kfd_device.c
│ ├── kfd_process.c
│ ├── kfd_svm.c
│ ├── kfd_svm.h
│ ├── kfd_migrate.c
│ └── ...
├── include/
│ └── kgd_kfd_interface.h
└── ...
3.2 KFD (Kernel Fusion Driver) 简介
KFD 的历史
目标 : 让 CPU 和 GPU 平等协作
理念 : 'GPU is a first-class compute citizen'
特性 : 统一地址空间、用户态队列、抢占支持
KFD 的核心组件 ┌───────────────────────────────────────┐
│ KFD 驱动 │
├───────────────────────────────────────┤
│ ┌────────────┐ ┌────────────┐ │
│ │进程管理 │ │设备管理 │ │
│ │kfd_process │ │kfd_device │ │
│ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌─────────────┐ │
│ │队列管理 │ │中断处理 │ │
│ │kfd_queue │ │kfd_interrupt│ │
│ └────────────┘ └─────────────┘ │
│ ┌────────────┐ ┌────────────┐ │
│ │内存管理 │ │拓扑管理 │ │
│ │kfd_svm │ │kfd_topology│ │
│ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ │
│ │事件管理 │ │调试支持 │ │
│ │kfd_events │ │kfd_debug │ │
│ └────────────┘ └────────────┘ │
└───────────────────────────────────────┘
1. 进程管理(kfd_process.c) struct kfd_process {
struct mm_struct *mm ;
struct mutex mutex ;
uint32_t pasid;
struct kfd_process_device *pdds [MAX_GPU_INSTANCE ];
struct svm_range_list svms ;
};
每个使用 KFD 的进程都有一个 kfd_process 结构
管理进程在所有 GPU 上的资源
持有 SVM 范围列表
2. 设备管理(kfd_device.c) struct kfd_dev {
struct amdgpu_device *adev ;
struct kfd_device_info device_info ;
const struct kfd2kgd_calls *kfd2kgd ;
struct dev_pagemap pgmap ;
};
GPU 硬件探测
↓
amdgpu 驱动加载
↓
调用 kgd2kfd_probe () ← AMDGPU 通知 KFD
↓
创建 kfd_dev 结构
↓
kgd2kfd_device_init () ← 初始化 KFD 设备
↓
注册到拓扑系统
↓
设备就绪
3. 字符设备接口(kfd_chardev.c) #define AMDKFD_IOC_CREATE_QUEUE
#define AMDKFD_IOC_DESTROY_QUEUE
#define AMDKFD_IOC_SET_MEMORY_POLICY
#define AMDKFD_IOC_SVM
用户空间调用: ioctl (kfd_fd, AMDKFD_IOC_SVM, &args)
↓
kfd_ioctl () 分发
↓
kfd_ioctl_svm () ← kfd_chardev.c
↓
svm_ioctl () ← kfd_svm.c
↓
处理具体的 SVM 操作(添加范围、设置属性等)
3.3 TTM (Translation Table Maps)
什么是 TTM TTM 是 DRM 子系统提供的 GPU 内存管理框架:
┌────────────────────────────────────┐
│ TTM 框架 │
├────────────────────────────────────┤
│ • 管理 VRAM 和 GTT 内存 │
│ • Buffer Object (BO) 管理 │
│ • 内存驱逐和交换 │
│ • 与系统内存交互 │
└────────────────────────────────────┘
↓ ↓
┌─────────┐ ┌─────────┐
│ VRAM │ │ GTT │
│(GPU 显存) │ │(系统内存)│
└─────────┘ └─────────┘
TTM 的内存域(Memory Domain)
#define TTM_PL_SYSTEM 0
#define TTM_PL_TT 1
#define TTM_PL_VRAM 2
#define TTM_PL_PRIV 3
Buffer Object (BO) struct amdgpu_bo {
struct ttm_buffer_object tbo ;
u64 vram_offset;
u32 preferred_domains;
u32 allowed_domains;
};
1 . 创建 BO amdgpu_bo_create ()
↓
分配 TTM 资源
↓
2 . 放置 BO(可能在 VRAM 或系统内存)
amdgpu_bo_pin () / ttm_bo_validate ()
↓
3 . CPU 访问
amdgpu_bo_kmap () ← 建立内核映射
↓
4 . GPU 访问
通过 GPU 页表映射
↓
5 . 驱逐(内存不足时)
ttm_bo_evict ()
↓
移动到系统内存
↓
6 . 销毁
amdgpu_bo_unref ()
TTM 与 SVM 的关系
struct svm_range_bo {
struct amdgpu_bo *bo ;
};
int svm_range_vram_node_new (...) {
ret = amdgpu_bo_create(...);
}
传统 BO:整块分配,显式管理
SVM:按需分配页面,自动迁移
3.4 GART 表的作用
什么是 GART GART (Graphics Address Remapping Table) 是 GPU 的地址重映射表,允许 GPU 访问系统内存。
没有 GART: GPU 只能访问 VRAM ✗
有 GART: GPU 可以通过 GART 访问系统 RAM ✓
GART 的工作原理 GPU 视角的地址空间:
┌──────────────────────┐
│ 0x0000 _0000 │
│ ... │ ← VRAM (直接映射)
│ VRAM End │
├──────────────────────┤
│ GART Start │
│ ... │ ← GART 窗口(映射系统 RAM)
│ GART End │
└──────────────────────┘
GART 映射表:
GPU 地址 → DMA 地址(系统内存物理地址)
GART 在 SVM 中的使用
svm_migrate_gart_map(ring, npages, dma_addr, &gart_addr, flags);
amdgpu_copy_buffer(ring, gart_addr, vram_addr, size,...);
SDMA 只能访问 GPU 地址空间
系统内存不在 GPU 地址空间中
GART 将系统内存"映射"到 GPU 地址空间
SDMA 现在可以访问系统内存了
系统内存页面
↓
建立 GART 映射 → GPU 可见地址
↓
SDMA 从 GPU 地址拷贝 → VRAM
3.5 SVM 在驱动中的位置
SVM 的模块划分 kfd_svm.c # SVM 核心逻辑
├─ 范围管理
│ ├─ svm_range_add ()
│ ├─ svm_range_unlink ()
│ └─ svm_range_split ()
├─ 页面映射
│ ├─ svm_range_map_to_gpu ()
│ ├─ svm_range_unmap_from_gpu ()
│ └─ svm_range_validate_and_map ()
├─ 缺页处理
│ ├─ svm_range_restore_pages ()
│ └─ 页面恢复逻辑
├─ MMU Notifier
│ └─ svm_range_cpu_invalidate_pagetables ()
├─ IOCTL 接口
│ └─ svm_ioctl ()
└─ 其他辅助功能
kfd_migrate.c # 页面迁移
├─ RAM → VRAM 迁移
├─ VRAM → RAM 迁移
├─ GART 映射管理
└─ SDMA 复制操作
kfd_svm.h # SVM 数据结构定义
SVM 与其他组件的交互 ┌──────────────────────────────┐
│ 用户空间 │
│ (ROCm Runtime) │
└──────────────────────────────┘
↓ IOCTL
========================
内核空间 ========================
↓
┌──────────────┐
│ kfd_chardev │ ← IOCTL 分发
└──────────────┘
↓
┌──────────────┐
│ kfd_ svm │ ← SVM 核心
└──────────────┘
↓ ↓ ↓
┌────┐ ┌────┐ ┌────┐
│HMM │ │TTM │ │VM │ ← 内核子系统
└────┘ └────┘ └────┘
↓ ↓ ↓
┌──────────────────┐
│ kfd_migrate │ ← 页面迁移
└──────────────────┘
↓
┌──────────────────┐
│ AMDGPU 驱动 │
│ (SDMA, VM, ...) │
└──────────────────┘
↓
┌──────────────────┐
│ GPU 硬件 │
└──────────────────┘
关键接口
1. KFD ↔ AMDGPU 接口
struct kfd2kgd_calls {
int (*map_memory_to_gpu)(...);
int (*unmap_memory_from_gpu)(...);
int (*submit_ib)(...);
};
2. SVM ↔ HMM 接口
ret = hmm_range_fault(&range);
ret = migrate_vma_setup(&migrate);
ret = migrate_vma_finalize(&migrate);
3. SVM ↔ 进程管理接口
struct kfd_process {
struct svm_range_list svms ;
};
svm_range_list_init(p);
svm_range_list_fini(p);
💡 重点提示
双驱动架构 :AMDGPU 负责图形,KFD 负责计算。SVM 在 KFD 中实现。
KFD 是核心 :SVM 的所有逻辑都在 drivers/gpu/drm/amd/amdkfd/ 目录下。
TTM 管理 VRAM :SVM 使用 TTM 的 BO 机制管理 GPU 显存。
GART 是桥梁 :GART 让 GPU 能够访问系统内存,是迁移的关键。
接口抽象良好 :KFD 通过接口与 AMDGPU 交互,解耦合度高。
⚠️ 常见误区 ❌ 误区 1 :'SVM 是 AMDGPU 驱动的功能'
✅ 正确理解:SVM 是 KFD 的功能,虽然依赖 AMDGPU,但主要代码在 KFD 中。
✅ 正确理解:SVM 使用 TTM 管理 VRAM,是合作关系。
✅ 正确理解:SVM 页面迁移也大量使用 GART。
✅ 正确理解:KFD 是 AMD 的实现,但 HSA 理念是通用的。
📝 实践练习
思考题 :
为什么需要独立的 KFD 驱动,而不是把所有功能放在 AMDGPU 中?
GART 表的大小有限制吗?如果限制,如何影响 SVM?
TTM 的驱逐机制如何与 SVM 协作?
ls -l /dev/kfd
cat /sys/class/kfd/kfd/topology/nodes/*/name
dmesg | grep -i svm
cd drivers/gpu/drm/amd/amdkfd
grep -n "module_init\|module_exit" kfd_module.c
grep -n "kgd2kfd" kfd_device.c | head -20
wc -l kfd_svm.c kfd_migrate.c
📚 本章小结
双驱动架构 :AMDGPU(图形)+ KFD(计算)
KFD 组件 :进程管理、设备管理、队列管理、SVM 等
TTM :GPU 内存管理框架,SVM 使用 TTM 管理 VRAM
GART :地址重映射表,让 GPU 访问系统内存
理解这些架构层次,有助于在后续章节深入 SVM 的具体实现。
📖 扩展阅读 微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online