AMD rocr-libhsakmt分析系列3-4:svm-reserve模式实现分析

1. 背景与原理

在AMD ROCm平台的内存管理中,SVM(Shared Virtual Memory)允许CPU和GPU共享统一的虚拟地址空间。init_svm_apertures函数负责初始化SVM地址空间(aperture),以便后续的内存分配和映射操作。该函数支持两种模式:

  • mmap模式:直接利用操作系统的虚拟地址分配能力,适用于GFXv9及以上架构,虚拟地址空间充足。

  • reserve模式 :在指定区间内预留一块连续的虚拟地址空间,适用于旧架构或特殊需求(如环境变量HSA_RESERVE_SVM启用)。

本文重点分析reserve模式的实现原理和具体流程。

2. 实现原理与应用场景

2.1 实现原理

Reserve模式的核心目标是:在指定的baselimit区间内,预留一块足够大的、连续的虚拟地址空间,供SVM使用。

  • 预留空间的大小优先为整个区间,若无法分配则逐步减半,直到满足最小要求(4GB)。

  • 预留空间必须对齐到GPU的Huge Page Size,保证性能和兼容性。

  • 预留空间的至少一半必须在GPU可寻址范围内,确保GPU能够访问大部分分配的SVM空间。

预留空间的实现很简单,就是mmap。当计算出起始地址和大小后,就可以申请了,关键实现函数如下:

cpp 复制代码
static void *reserve_address(void *addr, unsigned long long int len)
{
	void *ret_addr;

	if (len <= 0)
		return NULL;
    
    //匿名映射,请关注映射参数
	ret_addr = mmap(addr, len, PROT_NONE,
				 MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0);
	if (ret_addr == MAP_FAILED)
		return NULL;

	return ret_addr;
}

2.2 适用场景

  • 兼容性强:适用于虚拟地址空间有限或驱动/硬件不支持mmap模式的场景。

  • 可控性高:通过环境变量可强制启用reserve模式,便于调试和特殊需求。

  • 性能保障:Huge Page对齐和空间预留减少碎片,提高访问效率。

3. bo的svm地址分配与释放

reserve SVM 区域作为统一的虚拟地址池,所有分配和映射都在该区域内完成。在reserve SVM地址区间内申请memory,配套的申请和释放函数是reserved_aperture_allocate_aligned和reserved_aperture_release。原理与drm_mm的管理地址空间类似。使用list维护分配区间的元数据。

3.1 申请函数实现流程

1. 对齐处理

  • 如果请求的对齐小于 aperture 的默认对齐,则提升到默认对齐。

  • 对于大块分配,自动提升对齐到更高的2的幂(最多到 GPU_HUGE_PAGE_SIZE),以优化TLB性能。

  • 如果没有指定对齐(或对齐小于等于PAGE_SIZE),则采用"尾部对齐"策略:通过 offset 变量将分配区间尾部对齐到目标对齐边界,解决部分旧GPU的TLB问题。

2 分配区间扩展

  • 分配区间大小会加上 guard pages(保护页),防止越界访问。

3. 查找空闲区间

  • 遍历 aperture 的 vm_ranges 链表,查找足够大的"洞"。

  • 如果指定了 address,则从该地址开始查找,否则从 aperture base 开始按对齐递增查找。

  • 如果找到的空闲区间足够大,则分配;否则继续查找下一个区间。

4. 分配区间插入

  • 如果分配区间正好与前一个已分配区间相邻,则扩展该区间。

  • 否则,创建新的 vm_area_t 节点插入到链表中,维护分配区间元数据。

5 返回分配结果

3.2 释放函数的实现流程

  1. 区间对齐处理

    首先将释放的大小加上 guard pages(保护页),确保释放区间与分配时一致。

  2. 查找对应区间

    通过 vm_find 在 aperture 的 vm_ranges 链表中查找包含该地址的区间(vm_area_t)。

  3. 区间释放与调整

    • 如果释放区间正好等于整个已分配区间,则直接移除该区间节点(vm_remove_area)。

    • 如果释放区间是已分配区间的一部分,则根据释放位置(区间头、区间尾或中间)调整区间边界或拆分区间(vm_split_area)。

  4. 物理内存和 NUMA 策略处理

    • 如果 aperture 支持 CPU 访问(is_cpu_accessible),则重置 NUMA 策略(mbind),并用 mmap(PROT_NONE) 重新映射释放区间,保持地址空间预留但不可访问。

    • 如果 mmap 失败且 errno == ENOMEM,则先 munmap 再尝试 mmap,确保释放成功。

3.3 关键点

  • 所有分配和释放都在 aperture 的 fmm_mutex 保护下,保证线程安全。

  • 分配区间通过 vm_area_t 链表管理,支持动态分配和释放。

  • 对齐和保护页策略保证了分配区间的性能和安全性。

  • 释放时要保留区间。

相关推荐
阿巴~阿巴~10 小时前
基于UDP协议的英汉翻译服务系统:从网络通信到字典查询的完整机制
linux·服务器·网络·网络协议·udp协议·套接字绑定·英汉翻译服务系统
阿巴~阿巴~10 小时前
简易回声服务器实现与网络测试指南
linux·服务器·网络·udp协议·网络测试·udp套接字编程
凡间客12 小时前
Ansible安装与入门
linux·运维·ansible
君以思为故12 小时前
认识Linux -- 进程概念
linux·服务器
_OP_CHEN12 小时前
Linux网络编程:(八)GCC/G++ 编译器完全指南:从编译原理到实战优化,手把手教你玩转 C/C++ 编译
linux·运维·c++·编译和链接·gcc/g++·编译优化·静态链接与动态链接
阿乐艾官13 小时前
【十一、Linux管理网络安全】
linux·运维·web安全
Code Warrior14 小时前
【Linux】Socket 编程预备知识
linux·网络·c++
2301_8002561115 小时前
关系数据库小测练习笔记(1)
1024程序员节
摘星|15 小时前
架设一台NFS服务器,并按照以下要求配置
linux·运维·服务器
做运维的阿瑞15 小时前
Linux环境变量持久化完全指南
linux·运维·服务器