1. GPU KMD内存管理机制概述
在GPU内核模式驱动(Kernel Mode Driver, KMD)中,内存管理是最核心的子系统之一。不同于用户态简单的malloc/free,KMD需要处理物理内存映射、设备内存访问、DMA操作以及安全隔离等复杂场景。现代GPU通常需要管理以下几种内存类型:
- 设备本地内存(VRAM):GPU专用的高性能内存,通过PCIe BAR空间映射
- 系统共享内存:通过GART(Graphics Aperture Remapping Table)映射的主存区域
- IOMMU/SMMU保护内存:用于安全隔离和设备间通信的受保护内存区域
物理内存映射的核心挑战在于解决GPU 40/64位物理地址空间与CPU页表的协同问题。以NVIDIA的GP100架构为例,其支持48位虚拟地址和40位物理地址,需要通过多级页表实现与主机内存的地址转换。
关键点:现代GPU驱动必须同时处理至少三种不同的地址空间 - CPU虚拟地址、GPU虚拟地址和物理地址,这构成了内存管理的基础框架。
2. 物理内存映射实现细节
2.1 物理页帧管理
GPU驱动通过以下数据结构管理物理内存:
c复制struct gpu_page {
phys_addr_t phys_addr; // 物理地址
void* kmap; // 内核映射指针
u32 flags; // 页面属性标志
struct list_head list; // 链表管理
};
物理页分配通常采用伙伴系统(Buddy System)与slab分配器的组合:
- 大块连续内存通过
dma_alloc_coherent()获取 - 4KB小页使用
alloc_page(GFP_KERNEL) - 特殊内存(如写合并)需设置
PG_writecombine标志
2.2 地址空间映射
GPU驱动建立地址映射的关键步骤:
- 创建地址空间上下文:
c复制struct address_space *as = kmalloc(sizeof(*as), GFP_KERNEL);
init_rwsem(&as->lock);
INIT_LIST_H
