核心驱动程序基础设施¶
GPU 硬件结构¶
每个 ASIC 都是硬件块的集合。 我们将它们称为“IP”(知识产权块)。 每个 IP 封装了特定的功能。 IP 是有版本的,也可以混合和匹配。 例如,您可能有两个不同的 ASIC,它们都具有 System DMA (SDMA) 5.x IP。 驱动程序按 IP 排列。 有驱动程序组件来处理每个 IP 的初始化和操作。 还有一些较小的 IP,实际上不需要太多驱动程序交互。 这些最终会被归入 soc 文件中的常见内容中。 soc 文件(例如 vi.c、soc15.c nv.c)包含 SoC 本身方面的代码,而不是特定 IP。 例如,诸如 GPU 重置和寄存器访问功能之类的东西是 SoC 相关的。
APU 包含的不仅仅是 CPU 和 GPU,它还包含所有平台内容(音频、USB、GPIO 等)。 此外,许多组件在 CPU、平台和 GPU 之间共享(例如,SMU、PSP 等)。 特定组件(CPU、GPU 等)通常具有与其交互的接口,这些通用组件。 对于像 S0i3 这样的东西,需要在所有组件之间进行大量的协调,但这可能有点超出本节的范围。
关于 GPU,我们有以下主要 IP
- GMC(图形内存控制器)
这在较旧的 pre-vega 芯片上是一个专用 IP,但自 Vega 和更新的芯片以来,它在某种程度上变得分散。 它们现在为特定的 IP 或 IP 组配备了专用的内存集线器。 但是,我们在驱动程序中仍然将其视为单个组件,因为编程模型仍然非常相似。 这是 GPU 上的不同 IP 获取内存(VRAM 或系统内存)的方式。 它还为每个进程 GPU 虚拟地址空间提供支持。
- IH(中断处理程序)
这是 GPU 上的中断控制器。 所有 IP 都将其中断馈送到此 IP,它将它们聚合到一组环形缓冲区中,驱动程序可以解析这些缓冲区以处理来自不同 IP 的中断。
- PSP(平台安全处理器)
它处理 SoC 的安全策略并执行受信任的应用程序,并验证和加载其他块的固件。
- SMU(系统管理单元)
这是电源管理微控制器。 它管理整个 SoC。 驱动程序与它交互以控制时钟、电压、电源轨等电源管理功能。
- DCN(下一代显示控制器)
这是显示控制器。 它处理显示硬件。 在 显示核心 中进行了更详细的描述。
- SDMA(系统 DMA)
这是一个多用途 DMA 引擎。 内核驱动程序将其用于各种用途,包括分页和 GPU 页表更新。 它也暴露给用户空间,供用户模式驱动程序(OpenGL、Vulkan 等)使用。
- GC(图形和计算)
这是图形和计算引擎,即包含 3D 管道和着色器块的块。 这是 GPU 上迄今为止最大的块。 3D 管道有大量的子块。 除此之外,它还包含 CP 微控制器(ME、PFP、CE、MEC)和 RLC 微控制器。 它暴露给用户空间,供用户模式驱动程序(OpenGL、Vulkan、OpenCL 等)使用。 在 图形 (GFX) 和计算 中提供了更多详细信息。
- VCN(下一代视频核心)
这是多媒体引擎。 它处理视频和图像编码和解码。 它暴露给用户空间,供用户模式驱动程序(VA-API、OpenMAX 等)使用。
GFX、计算和 SDMA 总体行为¶
注意
为简单起见,只要在本节中使用术语块,它就表示 GFX、计算和 SDMA。
GFX、计算和 SDMA 共享一种类似的操作形式,可以对其进行抽象以方便理解这些块的行为。 请参见下图,该图说明了这些块的常见组件
在此图的中心部分,您可以看到两个硬件元件,一个称为 管道,另一个称为 队列; 重要的是要强调队列必须与管道相关联,反之亦然。 每个特定的硬件 IP 可能具有不同数量的管道,进而具有不同数量的队列; 例如,GFX 11 每个管道有两个管道和两个队列,用于 GFX 前端。
管道是处理队列中可用指令的硬件; 换句话说,它是一个执行插入队列中的操作的线程。 管道的一个关键特征是它们一次只能执行一个队列; 无论硬件在管道中有多少个队列,它每个管道只运行一个队列。
管道具有在硬件级别在队列之间交换的机制。 然而,它们仅利用被认为是映射的队列。 管道可以基于以下任何输入在队列之间切换
命令流;
逐个数据包;
其他硬件请求更改(例如,MES)。
管道中的队列由硬件队列描述符 (HQD) 定义。 与 HQD 概念相关联,我们有内存队列描述符 (MQD),它负责存储有关内存中每个可用队列状态的信息。 队列的状态包含诸如队列本身的 GPU 虚拟地址、保存区域、门铃等信息。 MQD 还存储 HQD 寄存器,这对于激活或停用给定的队列至关重要。 调度固件(例如,MES)负责从 MQD 加载 HQD,反之亦然。
队列切换过程也可能发生在固件请求抢占或取消映射队列时。 固件等待 HQD_ACTIVE 位变为低电平,然后将状态保存到 MQD 中。 为了使不同的队列变为活动队列,固件将 MQD 状态复制到 HQD 寄存器中并加载任何其他状态。 最后,它将 HQD_ACTIVE 位设置为高电平,以指示队列处于活动状态。 然后,管道将执行来自活动队列的工作。
驱动程序结构¶
通常,驱动程序具有特定 SoC 上所有 IP 的列表,并且对于诸如 init/fini/suspend/resume 之类的事情,或多或少只是遍历列表并处理每个 IP。
一些有用的构造
- KIQ(内核接口队列)
这是内核驱动程序用来管理 GFX/计算引擎上的其他 gfx 和计算队列的控制队列。 您可以使用它来映射/取消映射其他队列等。 这在 GFX 11 和更新的硬件上被 MES 取代。
- IB(间接缓冲区)
特定引擎的命令缓冲区。 您可以将命令写入内存块中,而不是直接将命令写入队列中,然后将指向该内存的指针放入队列中。 然后,硬件将跟踪指针并执行内存中的命令,然后返回到环形缓冲区中的其余命令。
内存域¶
AMDGPU_GEM_DOMAIN_CPU
不是 GPU 可访问的系统内存。 如果存在压力,此池中的内存可能会被交换到磁盘。
AMDGPU_GEM_DOMAIN_GTT
GPU 可访问的系统内存,通过 gart 映射到 GPU 的虚拟地址空间中。 Gart 内存线性化系统内存的非连续页面,允许 GPU 以线性方式访问系统内存。
AMDGPU_GEM_DOMAIN_VRAM
本地视频内存。 对于 APU,它是 BIOS 雕刻出的内存。
AMDGPU_GEM_DOMAIN_GDS
用于跨着色器线程共享数据的全局片上数据存储。
AMDGPU_GEM_DOMAIN_GWS
全局波同步,用于同步设备上所有波的执行。
AMDGPU_GEM_DOMAIN_OA
有序追加,由 3D 或计算引擎用于追加数据。
AMDGPU_GEM_DOMAIN_DOORBELL
门铃。 它是用于向用户模式队列发出信号的 MMIO 区域。
缓冲区对象¶
这定义了在 amdgpu_bo
缓冲区对象上进行操作的接口,该对象表示驱动程序使用的内存(VRAM、系统内存等)。 驱动程序为用户空间提供 DRM/GEM API。 然后,DRM/GEM API 使用这些接口来创建/销毁/设置缓冲区对象,然后由内核 TTM 内存管理器管理这些对象。 这些接口也供内核客户端在内部使用,包括 gfx、uvd 等,用于 GPU 使用的内核管理分配。
-
bool amdgpu_bo_is_amdgpu_bo(struct ttm_buffer_object *bo)¶
检查缓冲区对象是否为
amdgpu_bo
参数
struct ttm_buffer_object *bo
要检查的缓冲区对象
描述
使用与对象关联的销毁函数来确定这是否为 amdgpu_bo
。
返回
如果对象属于 amdgpu_bo
,则为 true,否则为 false。
-
void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)¶
设置缓冲区的放置位置
参数
struct amdgpu_bo *abo
amdgpu_bo
要设置放置位置的缓冲区对象u32 domain
请求的域
描述
根据请求的域和缓冲区的标志设置缓冲区的放置位置。
-
int amdgpu_bo_create_reserved(struct amdgpu_device *adev, unsigned long size, int align, u32 domain, struct amdgpu_bo **bo_ptr, u64 *gpu_addr, void **cpu_addr)¶
为内核使用创建保留的 BO
参数
struct amdgpu_device *adev
amdgpu 设备对象
unsigned long size
新 BO 的大小
int align
新 BO 的对齐方式
u32 domain
将其放置在何处
struct amdgpu_bo **bo_ptr
用于初始化结构中的 BO
u64 *gpu_addr
固定 BO 的 GPU 地址
void **cpu_addr
可选的 CPU 地址映射
描述
为内核内部使用分配和固定 BO,并返回仍保留的 BO。
注意
对于 bo_ptr,仅当 bo_ptr 指向 NULL 时才创建新 BO。
返回
成功时为 0,否则为负错误代码。
-
int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, uint64_t offset, uint64_t size, struct amdgpu_bo **bo_ptr, void **cpu_addr)¶
在特定位置为内核使用创建 BO
参数
struct amdgpu_device *adev
amdgpu 设备对象
uint64_t offset
BO 的偏移量
uint64_t size
BO 的大小
struct amdgpu_bo **bo_ptr
用于初始化结构中的 BO
void **cpu_addr
可选的 CPU 地址映射
描述
在 VRAM 中的特定偏移量处创建内核 BO。
返回
成功时为 0,否则为负错误代码。
-
int amdgpu_bo_create(struct amdgpu_device *adev, struct amdgpu_bo_param *bp, struct amdgpu_bo **bo_ptr)¶
创建一个
amdgpu_bo
缓冲区对象
参数
struct amdgpu_device *adev
amdgpu 设备对象
struct amdgpu_bo_param *bp
要用于缓冲区对象的参数
struct amdgpu_bo **bo_ptr
指向缓冲区对象指针的指针
描述
创建 amdgpu_bo
缓冲区对象。
返回
成功时为 0,失败时为负错误代码。
-
int amdgpu_bo_create_user(struct amdgpu_device *adev, struct amdgpu_bo_param *bp, struct amdgpu_bo_user **ubo_ptr)¶
创建
amdgpu_bo_user
缓冲区对象
参数
struct amdgpu_device *adev
amdgpu 设备对象
struct amdgpu_bo_param *bp
要用于缓冲区对象的参数
struct amdgpu_bo_user **ubo_ptr
指向缓冲区对象指针的指针
描述
创建一个要由用户应用程序使用的 BO;
返回
成功时为 0,失败时为负错误代码。
-
int amdgpu_bo_create_vm(struct amdgpu_device *adev, struct amdgpu_bo_param *bp, struct amdgpu_bo_vm **vmbo_ptr)¶
创建
amdgpu_bo_vm
缓冲区对象
参数
struct amdgpu_device *adev
amdgpu 设备对象
struct amdgpu_bo_param *bp
要用于缓冲区对象的参数
struct amdgpu_bo_vm **vmbo_ptr
指向缓冲区对象指针的指针
描述
创建一个用于 GPUVM 的 BO。
返回
成功时为 0,失败时为负错误代码。
-
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)¶
映射
amdgpu_bo
缓冲区对象
参数
struct amdgpu_bo *bo
要映射的
amdgpu_bo
缓冲区对象void **ptr
要返回的内核虚拟地址
描述
调用 ttm_bo_kmap() 设置内核虚拟映射; 调用 amdgpu_bo_kptr()
获取内核虚拟地址。
返回
成功时为 0,失败时为负错误代码。
-
void *amdgpu_bo_kptr(struct amdgpu_bo *bo)¶
返回缓冲区对象的内核虚拟地址
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象
描述
调用 ttm_kmap_obj_virtual() 获取内核虚拟地址
返回
缓冲区对象区域的虚拟地址。
-
void amdgpu_bo_kunmap(struct amdgpu_bo *bo)¶
取消映射
amdgpu_bo
缓冲区对象
-
struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo)¶
引用
amdgpu_bo
缓冲区对象
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象
描述
引用包含的 ttm_buffer_object
。
返回
指向 amdgpu_bo
缓冲区对象的引用计数指针。
-
void amdgpu_bo_unref(struct amdgpu_bo **bo)¶
取消引用
amdgpu_bo
缓冲区对象
参数
struct amdgpu_bo **bo
amdgpu_bo
缓冲区对象
描述
取消引用包含的 ttm_buffer_object
并清除指针
-
int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain)¶
固定
amdgpu_bo
缓冲区对象
参数
struct amdgpu_bo *bo
amdgpu_bo
要固定的缓冲区对象u32 domain
要固定到的域
描述
根据请求的域固定缓冲区对象。 如果内存是未绑定的 gart 内存,则将页面绑定到 gart 表中。 相应地调整 pin_count 和 pin_size。
固定意味着锁定内存中的页面以及将它们保持在固定的偏移量处。 当缓冲区无法移动时(例如,当显示缓冲区正在扫描输出时)需要这样做。
返回
成功时为 0,失败时为负错误代码。
-
void amdgpu_bo_unpin(struct amdgpu_bo *bo)¶
取消固定
amdgpu_bo
缓冲区对象
参数
struct amdgpu_bo *bo
amdgpu_bo
要取消固定的缓冲区对象
描述
减少 pin_count,如果 pin_count 达到 0,则清除标志。 相应地更改放置位置和固定大小。
返回
成功时为 0,失败时为负错误代码。
-
int amdgpu_bo_init(struct amdgpu_device *adev)¶
初始化内存管理器
参数
struct amdgpu_device *adev
amdgpu 设备对象
描述
调用 amdgpu_ttm_init() 初始化 amdgpu 内存管理器。
返回
成功时为 0,失败时为负错误代码。
-
void amdgpu_bo_fini(struct amdgpu_device *adev)¶
拆除内存管理器
-
int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags)¶
设置平铺标志
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象u64 tiling_flags
新标志
描述
使用新的平铺标志设置缓冲区对象的平铺标志。 由 GEM ioctl 或内核驱动程序用于设置缓冲区上的平铺标志。
返回
成功时为 0,失败时为负错误代码。
-
void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 *tiling_flags)¶
获取平铺标志
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象u64 *tiling_flags
返回的标志
描述
获取缓冲区对象的平铺标志。 由 GEM ioctl 或内核驱动程序用于设置缓冲区上的平铺标志。
-
int amdgpu_bo_set_metadata(struct amdgpu_bo *bo, void *metadata, u32 metadata_size, uint64_t flags)¶
设置元数据
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象void *metadata
新元数据
u32 metadata_size
新元数据的大小
uint64_t flags
新元数据的标志
描述
设置缓冲区对象的元数据、大小和标志。 通过 GEM ioctl 使用。
返回
成功时为 0,失败时为负错误代码。
-
int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, size_t buffer_size, uint32_t *metadata_size, uint64_t *flags)¶
获取元数据
参数
struct amdgpu_bo *bo
amdgpu_bo
缓冲区对象void *buffer
返回的元数据
size_t buffer_size
缓冲区的大小
uint32_t *metadata_size
返回的元数据的大小
uint64_t *flags
返回的元数据的标志
描述
获取缓冲区对象的元数据、大小和标志。 buffer_size 不应小于 metadata_size。 通过 GEM ioctl 使用。
返回
成功时为 0,失败时为负错误代码。
-
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *new_mem)¶
内存移动的通知
参数
struct ttm_buffer_object *bo
指向缓冲区对象的指针
bool evict
如果此移动将缓冲区从图形地址空间中逐出
struct ttm_resource *new_mem
用于支持 BO 的新资源
描述
将相应的 amdgpu_bo
缓冲区对象标记为无效,同时执行簿记。TTM 驱动程序回调,在 ttm 移动缓冲区时调用。
-
void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)¶
关于 BO 被释放的通知
参数
struct ttm_buffer_object *bo
指向缓冲区对象的指针
描述
清除 VRAM 缓冲区,其中的内容在内存释放之前不应泄漏。
-
vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)¶
关于内存错误的通知
参数
struct ttm_buffer_object *bo
指向缓冲区对象的指针
描述
通知驱动程序我们正在处理此 BO 上的错误并已保留它,同时执行簿记。TTM 驱动程序回调,用于处理 vm 错误。
返回
成功时为 0,失败时为负错误代码。
参数
struct amdgpu_bo *bo
有问题的缓冲区对象
struct dma_fence *fence
要添加的 fence
bool shared
如果 fence 应该以共享方式添加,则为 true
-
int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv, enum amdgpu_sync_mode sync_mode, void *owner, bool intr)¶
等待 BO 预留 fence
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct dma_resv *resv
要同步到的预留对象
enum amdgpu_sync_mode sync_mode
同步模式
void *owner
fence 所有者
bool intr
等待是否可中断
描述
从预留对象中提取 fence 并等待它们完成。
返回
成功时为 0,否则为 errno。
-
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr)¶
amdgpu_bo_sync_wait_resv 的包装器
参数
struct amdgpu_bo *bo
要等待的缓冲区对象
void *owner
fence 所有者
bool intr
等待是否可中断
描述
用于等待 BO 中 fence 的包装器。
返回
成功时为 0,否则为 errno。
-
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)¶
返回 bo 的 GPU 偏移量
参数
struct amdgpu_bo *bo
我们查询偏移量的 amdgpu 对象
注意
在调用此函数时,对象应该被固定或预留,为调试添加此检查可能很有用。
返回
对象的当前 GPU 偏移量。
-
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)¶
返回 bo 的 GPU 偏移量
参数
struct amdgpu_bo *bo
我们查询偏移量的 amdgpu 对象
返回
对象的当前 GPU 偏移量,不引发警告。
-
uint32_t amdgpu_bo_mem_stats_placement(struct amdgpu_bo *bo)¶
用于内存统计的 bo 放置
参数
struct amdgpu_bo *bo
我们应该查看的缓冲区对象
描述
BO 可以有多个首选放置位置,为了避免重复计数,我们希望将其归档在单个放置位置下的内存统计信息中。幸运的是,如果我们采用 preferred_domains 中设置的最高位,结果是相当合理的。
返回
BO 应该在哪个放置位置下进行统计。
-
uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev, uint32_t domain)¶
获取首选域
-
u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)¶
在 debugfs 文件中打印 BO 信息
参数
int id
BO 的索引或 Id
struct amdgpu_bo *bo
请求打印信息的 BO
struct seq_file *m
debugfs 文件
描述
在 debugfs 文件中打印 BO 信息
返回
BO 的大小,以字节为单位。
PRIME 缓冲区共享¶
以下回调实现用于通过 PRIME 在不同设备之间共享 GEM 缓冲区对象。
-
struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *attach)¶
帮助器,用于获取附件的 adev
参数
struct dma_buf_attachment *attach
附件
返回
如果附加设备是 amdgpu 设备或分区,则为 struct amdgpu_device *,否则为 NULL。
-
int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)¶
参数
struct dma_buf *dmabuf
我们附加到的 DMA-buf
struct dma_buf_attachment *attach
要添加的附件
描述
将附件作为用户添加到导出的 DMA-buf。
-
int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach)¶
参数
struct dma_buf_attachment *attach
要锁定的附件
描述
锁定支持 DMA-buf 的 BO,使其无法再移动。
-
void amdgpu_dma_buf_unpin(struct dma_buf_attachment *attach)¶
参数
struct dma_buf_attachment *attach
要解锁的附件
描述
解锁先前锁定的 BO 以使其再次可移动。
-
struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, enum dma_data_direction dir)¶
参数
struct dma_buf_attachment *attach
DMA-buf 附件
enum dma_data_direction dir
DMA 方向
描述
确保目标设备可以访问共享 DMA 缓冲区。目前,只需将其锁定到 GTT 域,所有 DMA 设备都应该可以访问它。
返回
sg_table 填充了要使用的 DMA 地址或带有负错误代码的 ERR_PTR。
-
void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir)¶
参数
struct dma_buf_attachment *attach
DMA-buf 附件
struct sg_table *sgt
要取消映射的 sg_table
enum dma_data_direction dir
DMA 方向
描述
当共享 DMA 缓冲区不再需要被另一个设备访问时,将调用此函数。目前,只需从 GTT 中解锁缓冲区。
参数
struct dma_buf *dma_buf
共享 DMA 缓冲区
enum dma_data_direction direction
DMA 传输方向
描述
在 CPU 访问共享 DMA 缓冲区的内存之前调用此函数。如果是读取访问,则尽可能将缓冲区移动到 GTT 域,以获得最佳 CPU 读取性能。
返回
成功时为 0,失败时为负错误代码。
-
struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, int flags)¶
参数
struct drm_gem_object *gobj
GEM BO
int flags
DRM_CLOEXEC 和 DRM_RDWR 等标志。
描述
主要工作由drm_gem_prime_export
帮助程序完成。
返回
表示来自给定设备的 GEM BO 的共享 DMA 缓冲区。
-
struct drm_gem_object *amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)¶
创建用于 DMA-buf 导入的 BO
参数
struct drm_device *dev
DRM 设备
struct dma_buf *dma_buf
DMA-buf
描述
为 DMA-buf 导入创建空的 SG BO。
返回
给定 DRM 设备的新 GEM BO,表示给定 DMA-buf 附件和分散/聚集表描述的内存。
-
void amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)¶
参数
struct dma_buf_attachment *attach
DMA-buf 附件
描述
使 DMA-buf 附件失效,确保我们在下次使用之前重新创建映射。
-
struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)¶
参数
struct drm_device *dev
DRM 设备
struct dma_buf *dma_buf
共享 DMA 缓冲区
描述
将 dma_buf 导入到驱动程序中,并可能创建一个新的 GEM 对象。
返回
表示给定设备的共享 DMA 缓冲区的 GEM BO。
-
bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, struct amdgpu_bo *bo)¶
检查 xgmi 是否可用于 P2P 传输
参数
struct amdgpu_device *adev
导入器的 amdgpu_device 指针
struct amdgpu_bo *bo
amdgpu 缓冲区对象
返回
如果可以通过 xgmi 访问 dmabuf,则为 True,否则为 False。
MMU 通知程序¶
对于一致的 userptr 处理,注册一个 MMU 通知程序,以通知驱动程序进程的页表更新。
当有人尝试使页表失效时,我们会阻止更新,直到问题页面上的所有操作都完成,然后这些页面被标记为已访问,如果不是只读访问,也会被标记为脏页。
使用问题 userptr 的新命令提交会延迟,直到所有页表失效都完成,并且我们再次看到一致的进程地址空间。
-
bool amdgpu_hmm_invalidate_gfx(struct mmu_interval_notifier *mni, const struct mmu_notifier_range *range, unsigned long cur_seq)¶
回调以通知有关 mm 更改
参数
struct mmu_interval_notifier *mni
范围 (mm) 即将更新
const struct mmu_notifier_range *range
有关失效的详细信息
unsigned long cur_seq
要传递给 mmu_interval_set_seq() 的值
描述
阻止对 BO 的操作完成,并将页面标记为已访问,并可能标记为脏页。
-
bool amdgpu_hmm_invalidate_hsa(struct mmu_interval_notifier *mni, const struct mmu_notifier_range *range, unsigned long cur_seq)¶
回调以通知有关 mm 更改
参数
struct mmu_interval_notifier *mni
范围 (mm) 即将更新
const struct mmu_notifier_range *range
有关失效的详细信息
unsigned long cur_seq
要传递给 mmu_interval_set_seq() 的值
描述
我们暂时逐出附加到此范围的 BO。这需要逐出进程的所有用户模式队列。
-
int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr)¶
注册 BO 以进行通知程序更新
参数
struct amdgpu_bo *bo
amdgpu 缓冲区对象
unsigned long addr
我们应该监视的 userptr addr
描述
在指定地址为给定 BO 注册 mmu_notifier。成功时返回 0,如果出现任何问题,则返回 -ERRNO。
-
void amdgpu_hmm_unregister(struct amdgpu_bo *bo)¶
注销 BO 以进行通知程序更新
参数
struct amdgpu_bo *bo
amdgpu 缓冲区对象
描述
从缓冲区对象中删除 mmu 通知程序的任何注册更新。
AMDGPU 虚拟内存¶
GPUVM 是 GPU 上提供的 MMU 功能。GPUVM 类似于旧 asic 上的传统 GART,但是,与其为整个 GPU 提供单个全局 GART 表,不如在任何给定时间都可以有多个 GPUVM 页表处于活动状态。GPUVM 页表可以包含 VRAM 页面和系统页面的混合(内存和 MMIO),并且系统页面可以映射为 snooped(缓存的系统页面)或 unsnooped(未缓存的系统页面)。
每个活动的 GPUVM 都有一个与之关联的 ID,并且每个 VMID 都有一个页表链接。执行命令缓冲区时,内核会告诉引擎要为该命令缓冲区使用哪个 VMID。VMID 在提交命令时动态分配。用户空间驱动程序维护自己的地址空间,并且内核会在提交命令缓冲区并分配 VMID 时相应地设置其页面表。硬件最多支持 16 个活动 GPUVM。
每个 GPUVM 都由 1-2 或 1-5 级页表表示,具体取决于 ASIC 系列。GPUVM 支持每个页面上的 RWX 属性以及加密和缓存属性等其他功能。
VMID 0 是特殊的。它是内核驱动程序使用的 GPUVM。除了由页表管理的 aperture 之外,VMID 0 还有几个其他 aperture。有一个用于直接访问 VRAM 的 aperture,并且有一个传统的 AGP aperture,它只是将访问直接转发到匹配的系统物理地址(或者存在 IOMMU 时的 IOVA)。这些 aperture 提供对这些内存的直接访问,而不会产生页表的开销。VMID 0 由内核驱动程序用于内存管理等任务。
GPU 客户端(即 GPU 上的引擎)使用 GPUVM VMID 来访问内存。对于用户应用程序,每个应用程序都可以有自己唯一的 GPUVM 地址空间。应用程序管理地址空间,内核驱动程序管理每个进程的 GPUVM 页表。如果 GPU 客户端访问无效页面,它将生成 GPU 页错误,类似于访问 CPU 上的无效页面。
-
struct amdgpu_prt_cb¶
帮助程序,用于从 fence 回调禁用部分驻留纹理功能
定义:
struct amdgpu_prt_cb {
struct amdgpu_device *adev;
struct dma_fence_cb cb;
};
成员
adev
amdgpu 设备
cb
回调
-
struct amdgpu_vm_tlb_seq_struct¶
帮助程序,用于递增 TLB 刷新序列
定义:
struct amdgpu_vm_tlb_seq_struct {
struct amdgpu_vm *vm;
struct dma_fence_cb cb;
};
成员
vm
指向 amdgpu_vm 结构的指针,用于设置 fence 序列
cb
回调
-
int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm, u32 pasid)¶
管理 pasid 和 vm 指针映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
amdgpu_vm 指针
u32 pasid
VM 在此 GPU 上使用的 pasid
描述
设置此 VM 在此 GPU 上使用的 pasid,也可以通过传入零来删除 pasid。
-
void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 被驱逐
参数
struct amdgpu_vm_bo_base *vm_bo
被驱逐的 vm_bo
描述
PD/PT 和每个 VM BO 的状态,它们不在它们应该在的位置。
-
void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 已移动
参数
struct amdgpu_vm_bo_base *vm_bo
已移动的 vm_bo
描述
每个 VM BO 的状态,它们已移动,但该更改尚未反映在页表中。
-
void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 空闲
参数
struct amdgpu_vm_bo_base *vm_bo
现在空闲的 vm_bo
描述
PD/PT 和每个 VM BO 的状态,它们已经过状态机,现在处于空闲状态。
-
void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 已失效
参数
struct amdgpu_vm_bo_base *vm_bo
现在失效的 vm_bo
描述
普通 BO 的状态,它们已失效,并且该更改尚未反映在 PT 中。
-
void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 被驱逐
参数
struct amdgpu_vm_bo_base *vm_bo
被驱逐的 vm_bo
描述
用户模式队列使用的 BO 的状态,它们不在它们应该在的位置。
-
void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 已重定位
参数
struct amdgpu_vm_bo_base *vm_bo
已重定位的 vm_bo
描述
PD/PT 的状态,它们需要更新其父 PD。对于根 PD,只需移动到空闲状态。
-
void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)¶
vm_bo 已完成
参数
struct amdgpu_vm_bo_base *vm_bo
现在完成的 vm_bo
描述
普通 BO 的状态,它们已失效,并且该更改已在 PT 中更新。
-
void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)¶
重置 vm_bo 状态机
参数
struct amdgpu_vm *vm
要重置状态机的 VM
描述
将 VM 中的所有 vm_bo 对象移动到一种状态,在该状态下它们将在验证期间再次更新。
用于更新共享内存统计信息的助手函数
参数
struct amdgpu_vm_bo_base *base
用于跟踪 VM 中 BO 使用情况的基本结构
描述
获取 vm status_lock 并更新共享内存统计信息。如果基本统计信息已更改(例如,缓冲区已移动),则也需要调用 amdgpu_vm_update_stats。
当 bo 被共享/取消共享时的回调
参数
struct amdgpu_bo *bo
amdgpu 缓冲区对象
描述
如果需要,更新所有 vm 的每个 VM 统计信息,从私有更改为共享,反之亦然。
-
void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base, struct ttm_resource *res, int sign)¶
用于更新普通内存统计信息的助手函数
参数
struct amdgpu_vm_bo_base *base
用于跟踪 VM 中 BO 使用情况的基本结构
struct ttm_resource *res
ttm_resource 用于统计,可能或可能不是 bo->tbo.resource
int sign
如果我们应该从统计信息中添加 (+1) 或减去 (-1)
描述
调用方需要持有 vm status_lock。当需要同时进行多次更新时很有用。
-
void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base, struct ttm_resource *res, int sign)¶
用于更新普通内存统计信息的助手函数
参数
struct amdgpu_vm_bo_base *base
用于跟踪 VM 中 BO 使用情况的基本结构
struct ttm_resource *res
ttm_resource 用于统计,可能或可能不是 bo->tbo.resource
int sign
如果我们应该从统计信息中添加 (+1) 或减去 (-1)
描述
当 bo 被添加/删除/移动时,更新基本内存统计信息。
-
void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base, struct amdgpu_vm *vm, struct amdgpu_bo *bo)¶
将 bo 添加到与 vm 关联的 bos 列表
参数
struct amdgpu_vm_bo_base *base
用于跟踪 VM 中 BO 使用情况的基本结构
struct amdgpu_vm *vm
要将 bo 添加到的 vm
struct amdgpu_bo *bo
amdgpu 缓冲区对象
描述
初始化 bo_va_base 结构并将其添加到适当的列表中
-
int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec, unsigned int num_fences)¶
在 drm_exec 中锁定 PD
参数
struct amdgpu_vm *vm
提供 BO 的 vm
struct drm_exec *exec
drm 执行上下文
unsigned int num_fences
要保留的额外 fence 数量
描述
在 DRM 执行上下文中锁定 VM 根 PD。
-
void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, struct amdgpu_vm *vm)¶
将所有 BO 移动到 LRU 的末尾
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_vm *vm
提供 BO 的 vm
描述
将所有 BO 移动到 LRU 的末尾,并记住它们的位置以将它们放在一起。
-
uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm)¶
返回页表重新生成计数器
参数
struct amdgpu_device *adev
amdgpu_device
struct amdgpu_vm *vm
要检查的可选 VM,可能为 NULL
描述
返回页表重新生成令牌,以允许检查提交是否仍然有效以使用此 VM。VM 参数可能为 NULL,在这种情况下,将仅使用 VRAM 丢失计数器。
-
int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket, int (*validate)(void *p, struct amdgpu_bo *bo), void *param)¶
验证 VM 中跟踪的已驱逐 BO
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_vm *vm
提供 BO 的 vm
struct ww_acquire_ctx *ticket
用于保留 VM 的可选保留票证
int (*validate)(void *p, struct amdgpu_bo *bo)
执行验证的回调
void *param
验证回调的参数
描述
如有必要,在命令提交时验证页表 BO 和每个 VM BO。如果给定了票证,还尝试验证已驱逐的用户队列 BO。它们必须已使用给定的票证保留。
返回
验证结果。
-
bool amdgpu_vm_ready(struct amdgpu_vm *vm)¶
检查 VM 是否已准备好进行更新
参数
struct amdgpu_vm *vm
要检查的 VM
描述
检查所有 VM PD/PT 是否已准备好进行更新
返回
如果 VM 未被驱逐,则为 True。
-
void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev)¶
检查 ASIC 是否有计算 VM 错误
参数
struct amdgpu_device *adev
amdgpu_device 指针
-
bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, struct amdgpu_job *job)¶
检查作业是否需要管道同步。
参数
struct amdgpu_ring *ring
将在其上提交作业的环
struct amdgpu_job *job
要提交的作业
返回
如果需要同步,则为 True。
-
int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync)¶
硬件刷新 VM
参数
struct amdgpu_ring *ring
用于刷新的环
struct amdgpu_job *job
相关作业
bool need_pipe_sync
是否需要管道同步
描述
在必要时发出 VM 刷新。
返回
成功时为 0,否则为 errno。
-
struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, struct amdgpu_bo *bo)¶
查找特定 vm 和 bo 的 bo_va
参数
struct amdgpu_vm *vm
请求的 vm
struct amdgpu_bo *bo
请求的缓冲区对象
描述
在请求的 vm 中查找 bo。在 bos vm 列表中搜索请求的 vm。返回找到的 bo_va,如果未找到,则返回 NULL
对象必须保留!
返回
找到的 bo_va 或 NULL。
-
uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr)¶
解析 addr 的 gart 映射
参数
const dma_addr_t *pages_addr
用于查找的可选 DMA 地址
uint64_t addr
未映射的 addr
描述
查找 pte 解析到的页面的物理地址。
返回
页表条目的指针。
-
int amdgpu_vm_update_pdes(struct amdgpu_device *adev, struct amdgpu_vm *vm, bool immediate)¶
确保所有目录都有效
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
bool immediate
立即提交到分页队列
描述
确保所有目录都是最新的。
返回
成功则为 0,失败则为错误。
-
void amdgpu_vm_tlb_seq_cb(struct dma_fence *fence, struct dma_fence_cb *cb)¶
确保增加 tlb 序列
参数
struct dma_fence *fence
未使用
struct dma_fence_cb *cb
回调结构
描述
增加 tlb 序列以确保未来的 CS 执行 VM 刷新。
-
void amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params, struct dma_fence **fence, struct amdgpu_vm_tlb_seq_struct *tlb_cb)¶
准备 TLB 刷新
参数
struct amdgpu_vm_update_params *params
更新参数
struct dma_fence **fence
与 TLB 刷新同步的输入 fence
struct amdgpu_vm_tlb_seq_struct *tlb_cb
回调结构
描述
增加 tlb 序列以确保未来的 CS 执行 VM 刷新。
-
int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, bool immediate, bool unlocked, bool flush_tlb, bool allow_override, struct amdgpu_sync *sync, uint64_t start, uint64_t last, uint64_t flags, uint64_t offset, uint64_t vram_base, struct ttm_resource *res, dma_addr_t *pages_addr, struct dma_fence **fence)¶
更新 vm 页表中的范围
参数
struct amdgpu_device *adev
用于命令的 amdgpu_device 指针
struct amdgpu_vm *vm
要更新范围的 VM
bool immediate
页面错误中的立即提交
bool unlocked
MM 回调期间的解锁失效
bool flush_tlb
更新完成后触发 tlb 失效
bool allow_override
更改本地 NUMA 节点的 MTYPE
struct amdgpu_sync *sync
我们需要同步的 fence
uint64_t start
映射范围的开始
uint64_t last
上次映射的条目
uint64_t flags
条目的标志
uint64_t offset
节点和 pages_addr 中的偏移量
uint64_t vram_base
vram 映射的基础
struct ttm_resource *res
要映射的 ttm_resource
dma_addr_t *pages_addr
用于映射的 DMA 地址
struct dma_fence **fence
可选的结果 fence
描述
填充 start 和 last 之间的页表条目。
返回
成功则为 0,失败则为负错误代码。
-
int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, bool clear)¶
更新 vm 页表中的所有 BO 映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
请求的 BO 和 VM 对象
bool clear
如果为 true,则清除条目
描述
填充 bo_va 的页表条目。
返回
成功则为 0,失败则为 -EINVAL。
-
void amdgpu_vm_update_prt_state(struct amdgpu_device *adev)¶
更新全局 PRT 状态
参数
struct amdgpu_device *adev
amdgpu_device 指针
-
void amdgpu_vm_prt_get(struct amdgpu_device *adev)¶
添加 PRT 用户
参数
struct amdgpu_device *adev
amdgpu_device 指针
-
void amdgpu_vm_prt_put(struct amdgpu_device *adev)¶
删除 PRT 用户
参数
struct amdgpu_device *adev
amdgpu_device 指针
-
void amdgpu_vm_prt_cb(struct dma_fence *fence, struct dma_fence_cb *_cb)¶
用于更新 PRT 状态的回调
参数
struct dma_fence *fence
回调的 fence
struct dma_fence_cb *_cb
回调函数
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct dma_fence *fence
回调的 fence
-
void amdgpu_vm_free_mapping(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo_va_mapping *mapping, struct dma_fence *fence)¶
释放映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
struct amdgpu_bo_va_mapping *mapping
要释放的映射
struct dma_fence *fence
取消映射操作的 fence
描述
释放映射,并确保我们减少 PRT 使用计数(如果适用)。
-
void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)¶
完成所有 prt 映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
描述
注册清理回调以在 VM 死后禁用 PRT 支持。
-
int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct dma_fence **fence)¶
清除 PT 中已释放的 BO
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
struct dma_fence **fence
可选的结果 fence(如果不需要执行任何操作或发生错误,则保持不变)
描述
确保所有已释放的 BO 在 PT 中都被清除。PT 必须被预留,并且互斥锁必须被锁定!
返回
成功返回 0。
-
int amdgpu_vm_handle_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)¶
处理 PT 中移动的 BO
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
struct ww_acquire_ctx *ticket
用于保留 VM 的可选保留票证
描述
确保所有移动的 BO 在 PT 中都被更新。
PT 必须被预留!
返回
成功返回 0。
-
int amdgpu_vm_flush_compute_tlb(struct amdgpu_device *adev, struct amdgpu_vm *vm, uint32_t flush_type, uint32_t xcc_mask)¶
刷新计算 VM 上的 TLB
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
uint32_t flush_type
刷新类型
uint32_t xcc_mask
需要刷新 TLB 的计算分区所属的 XCC 掩码。
描述
如果需要,刷新计算 VM 的 TLB。
返回
成功返回 0。
-
struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo *bo)¶
将 bo 添加到特定的 vm
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
struct amdgpu_bo *bo
amdgpu 缓冲区对象
描述
将 **bo** 添加到请求的 vm 中。将 **bo** 添加到与 vm 关联的 bo 列表中
对象必须保留!
返回
新添加的 bo_va,失败则返回 NULL
-
void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, struct amdgpu_bo_va_mapping *mapping)¶
插入新的映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
bo_va 用于存储地址
struct amdgpu_bo_va_mapping *mapping
要插入的映射
描述
将新的映射插入到所有结构中。
-
int amdgpu_vm_bo_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t saddr, uint64_t offset, uint64_t size, uint64_t flags)¶
将 bo 映射到 vm 内部
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
bo_va 用于存储地址
uint64_t saddr
bo 映射的位置
uint64_t offset
bo 中请求的偏移量
uint64_t size
bo 大小,以字节为单位
uint64_t flags
页面的属性(读/写/有效/等等)
描述
在指定的地址将 BO 的映射添加到 VM 中。
对象必须在外部预留和取消预留!
返回
成功则为 0,失败则为错误。
-
int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t saddr, uint64_t offset, uint64_t size, uint64_t flags)¶
将 bo 映射到 vm 内部,替换现有的映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
bo_va 用于存储地址
uint64_t saddr
bo 映射的位置
uint64_t offset
bo 中请求的偏移量
uint64_t size
bo 大小,以字节为单位
uint64_t flags
页面的属性(读/写/有效/等等)
描述
在指定的地址将 BO 的映射添加到 VM 中。在此过程中替换现有的映射。
对象必须在外部预留和取消预留!
返回
成功则为 0,失败则为错误。
-
int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t saddr)¶
从 vm 中移除 bo 映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
bo_va 用于从中移除地址
uint64_t saddr
BO 映射的位置
描述
从 VM 中移除在指定的地址的 BO 映射。
对象必须在外部预留和取消预留!
返回
成功则为 0,失败则为错误。
-
int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, struct amdgpu_vm *vm, uint64_t saddr, uint64_t size)¶
移除特定范围内的所有映射
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
要使用的 VM 结构
uint64_t saddr
范围的起点
uint64_t size
范围的大小
描述
移除一个范围内的所有映射,并适当地拆分它们。
返回
成功则为 0,失败则为错误。
-
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, uint64_t addr)¶
按地址查找映射
参数
struct amdgpu_vm *vm
请求的 VM
uint64_t addr
地址
描述
通过地址查找映射。
返回
与 addr 匹配的 amdgpu_bo_va_mapping,如果没有则返回 NULL
-
void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)¶
跟踪所有预留的映射
参数
struct amdgpu_vm *vm
请求的 vm
struct ww_acquire_ctx *ticket
CS ticket
描述
跟踪命令提交期间预留的 BO 的所有映射。
-
void amdgpu_vm_bo_del(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va)¶
从特定的 vm 中移除 bo
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_bo_va *bo_va
请求的 bo_va
描述
从请求的 vm 中移除 **bo_va->bo**。
对象必须被预留!
-
bool amdgpu_vm_evictable(struct amdgpu_bo *bo)¶
检查我们是否可以驱逐 VM
参数
struct amdgpu_bo *bo
VM 的页表。
描述
检查是否可以驱逐 VM。
-
void amdgpu_vm_bo_invalidate(struct amdgpu_bo *bo, bool evicted)¶
将 bo 标记为无效
参数
struct amdgpu_bo *bo
amdgpu 缓冲区对象
bool evicted
BO 是否被驱逐
描述
将 **bo** 标记为无效。
-
void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem, bool evicted)¶
处理 BO 移动
参数
struct amdgpu_bo *bo
amdgpu 缓冲区对象
struct ttm_resource *new_mem
BO 移动的新位置
bool evicted
BO 是否被驱逐
描述
更新新位置的内存统计信息,并将 **bo** 标记为无效。
-
uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)¶
以 2 的幂计算 VM 页表大小
参数
uint64_t vm_size
VM 大小
返回
VM 页表,以 2 的幂表示
-
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, uint32_t fragment_size_default, unsigned max_level, unsigned max_bits)¶
调整 vm 大小、块大小和片段大小
参数
struct amdgpu_device *adev
amdgpu_device 指针
uint32_t min_vm_size
如果设置为 auto,则最小 vm 大小(GB)
uint32_t fragment_size_default
默认 PTE 片段大小
unsigned max_level
最大 VMPT 级别
unsigned max_bits
地址空间的最大位数
-
long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)¶
等待 VM 变为 idle 状态
参数
struct amdgpu_vm *vm
要等待的 VM 对象
long timeout
等待 VM 变为 idle 状态的超时时间
-
void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info)¶
减少 vm task_info 指针的引用计数
参数
struct amdgpu_task_info *task_info
正在讨论的 task_info 结构。
描述
在最后一次 put 操作时释放 vm task_info 指针
-
struct amdgpu_task_info *amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm)¶
提取 vm 的任务信息。
参数
struct amdgpu_vm *vm
要从中获取信息的 VM
描述
返回引用计数的 task_info 结构,必须使用 amdgpu_vm_put_task_info 减少其引用计数。
-
struct amdgpu_task_info *amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid)¶
提取 PASID 的任务信息。
参数
struct amdgpu_device *adev
drm 设备指针
u32 pasid
VM 的 PASID 标识符
描述
返回引用计数的 task_info 结构,必须使用 amdgpu_vm_put_task_info 减少其引用计数。
-
void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)¶
设置 VM 的任务信息。
参数
struct amdgpu_vm *vm
要设置信息的 vm
-
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)¶
初始化 vm 实例
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
int32_t xcp_id
GPU 分区选择 id
描述
初始化 **vm** 字段。
返回
成功则为 0,失败则为错误。
-
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)¶
将 GFX VM 转换为计算 VM
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
描述
这仅适用于没有添加任何 BO 且尚未分配页表的 GFX VM。
更改以下 VM 参数:- use_cpu_for_update - pte_supports_ats
重新初始化页目录以反映更改的 ATS 设置。
返回
成功返回 0,错误返回 -errno。
-
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)¶
拆卸 vm 实例
参数
struct amdgpu_device *adev
amdgpu_device 指针
struct amdgpu_vm *vm
请求的 vm
描述
拆卸 **vm**。取消绑定 VM 并从 vm bo 列表中移除所有 bo
-
void amdgpu_vm_manager_init(struct amdgpu_device *adev)¶
初始化 VM 管理器
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
初始化 VM 管理器结构
-
void amdgpu_vm_manager_fini(struct amdgpu_device *adev)¶
清理 VM 管理器
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
清理 VM 管理器并释放资源。
-
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)¶
管理 vm hub 的 VMID 预留。
参数
struct drm_device *dev
drm 设备指针
void *data
drm_amdgpu_vm
struct drm_file *filp
drm 文件指针
返回
成功返回 0,错误返回 -errno。
-
bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, u32 vmid, u32 node_id, uint64_t addr, uint64_t ts, bool write_fault)¶
优雅地处理 VM 故障。
参数
struct amdgpu_device *adev
amdgpu 设备指针
u32 pasid
VM 的 PASID
u32 vmid
VMID,仅用于 GFX 9.4.3。
u32 node_id
IH cookie 中接收的 Node_id。仅适用于 GFX 9.4.3。
uint64_t addr
故障地址
uint64_t ts
故障的时间戳
bool write_fault
true 表示写故障,false 表示读故障
描述
尝试优雅地处理 VM 故障。如果故障已处理且不应再报告,则返回 true。
-
void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)¶
打印 VM 的 BO 信息
参数
struct amdgpu_vm *vm
请求打印 BO 信息的 VM
struct seq_file *m
debugfs 文件
描述
在 VM 的 debugfs 文件中打印 BO 信息
-
void amdgpu_vm_update_fault_cache(struct amdgpu_device *adev, unsigned int pasid, uint64_t addr, uint32_t status, unsigned int vmhub)¶
更新缓存的故障信息。
参数
struct amdgpu_device *adev
amdgpu 设备指针
unsigned int pasid
VM 的 PASID
uint64_t addr
故障地址
uint32_t status
GPUVM 故障状态寄存器
unsigned int vmhub
哪个 vmhub 发生了故障
描述
缓存故障信息,供用户空间以后在调试中使用。
-
bool amdgpu_vm_is_bo_always_valid(struct amdgpu_vm *vm, struct amdgpu_bo *bo)¶
检查 BO 是否 VM 始终有效
参数
struct amdgpu_vm *vm
要测试的 VM。
struct amdgpu_bo *bo
要测试的 BO。
描述
如果 BO 与根 PD 共享 dma_resv 对象,并且保证在 VM 内部始终有效,则返回 true。
中断处理¶
GPU 硬件中生成的中断会引发中断请求,这些请求会传递给 amdgpu IRQ 处理程序,该处理程序负责检测中断的来源和类型,并分派匹配的处理程序。如果处理中断需要调用可能休眠的内核函数,则处理会被分派给工作处理程序。
如果模块参数未禁用 MSI 功能,则将启用 MSI 支持。
对于可能由另一个驱动程序驱动的 GPU 中断源,将使用 IRQ 域支持(在虚拟 IRQ 和硬件 IRQ 之间进行映射)。
-
void amdgpu_irq_disable_all(struct amdgpu_device *adev)¶
禁用*所有*中断
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
禁用来自所有来源的所有类型的中断。
-
irqreturn_t amdgpu_irq_handler(int irq, void *arg)¶
IRQ 处理程序
参数
int irq
IRQ 编号(未使用)
void *arg
指向 DRM 设备的指针
描述
amdgpu 驱动程序(所有 ASIC)的 IRQ 处理程序。
返回
处理 IRQ 的结果,由 irqreturn_t
定义
-
void amdgpu_irq_handle_ih1(struct work_struct *work)¶
启动 IH1 的处理
参数
struct work_struct *work
struct amdgpu_irq 中的工作结构
描述
启动处理 IH 环 1。
-
void amdgpu_irq_handle_ih2(struct work_struct *work)¶
启动 IH2 的处理
参数
struct work_struct *work
struct amdgpu_irq 中的工作结构
描述
启动 IH 环 2 的处理。
-
void amdgpu_irq_handle_ih_soft(struct work_struct *work)¶
启动 ih_soft 的处理
参数
struct work_struct *work
struct amdgpu_irq 中的工作结构
描述
启动 IH 软环的处理。
-
bool amdgpu_msi_ok(struct amdgpu_device *adev)¶
检查是否启用了 MSI 功能
参数
struct amdgpu_device *adev
amdgpu 设备指针(未使用)
描述
检查是否已通过模块参数禁用 MSI 功能(所有 ASIC)。
返回
如果允许启用 MSI,则为 *true*,否则为 *false*
-
int amdgpu_irq_init(struct amdgpu_device *adev)¶
初始化中断处理
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
设置热插拔和重置中断的工作函数,启用 MSI 功能,初始化垂直消隐、热插拔和重置中断处理。
返回
成功时为 0,失败时为错误代码
-
void amdgpu_irq_fini_sw(struct amdgpu_device *adev)¶
关闭中断处理
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
拆卸热插拔和重置中断的工作函数,禁用 MSI 功能,关闭垂直消隐、热插拔和重置中断处理,关闭来自所有源的中断(所有 ASIC)。
-
int amdgpu_irq_add_id(struct amdgpu_device *adev, unsigned int client_id, unsigned int src_id, struct amdgpu_irq_src *source)¶
注册 IRQ 源
参数
struct amdgpu_device *adev
amdgpu 设备指针
unsigned int client_id
客户端 ID
unsigned int src_id
源 ID
struct amdgpu_irq_src *source
IRQ 源指针
描述
在客户端上注册 IRQ 源。
返回
成功时为 0,否则为错误代码
-
void amdgpu_irq_dispatch(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)¶
将 IRQ 分派到 IP 块
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_ih_ring *ih
中断环实例
描述
将 IRQ 分派到 IP 块。
-
void amdgpu_irq_delegate(struct amdgpu_device *adev, struct amdgpu_iv_entry *entry, unsigned int num_dw)¶
将 IV 委托给软 IH 环
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_iv_entry *entry
IV 条目
unsigned int num_dw
IV 的大小
描述
将 IV 委托给软 IH 环并安排对其进行处理。 如果由于某种原因硬件委托给 IH1 或 IH2 不起作用,则使用此方法。
-
int amdgpu_irq_update(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned int type)¶
更新硬件中断状态
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_irq_src *src
中断源指针
unsigned int type
中断类型
描述
更新特定源的中断状态(所有 ASIC)。
-
void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)¶
更新所有源的中断状态
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
重置后恢复时,更新所有源上所有类型中断的状态。
-
int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned int type)¶
启用中断
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_irq_src *src
中断源指针
unsigned int type
中断类型
描述
在指定源上启用指定类型的中断(所有 ASIC)。
返回
成功时为 0,否则为错误代码
-
int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned int type)¶
禁用中断
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_irq_src *src
中断源指针
unsigned int type
中断类型
描述
在指定源上启用指定类型的中断(所有 ASIC)。
返回
成功时为 0,否则为错误代码
-
bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned int type)¶
检查是否已启用中断
参数
struct amdgpu_device *adev
amdgpu 设备指针
struct amdgpu_irq_src *src
中断源指针
unsigned int type
中断类型
描述
检查给定类型的中断是否已在给定源上启用。
返回
如果已启用中断,则为 *true*;如果已禁用中断或参数无效,则为 *false*
-
int amdgpu_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)¶
创建虚拟 IRQ 编号和硬件 IRQ 编号之间的映射
参数
struct irq_domain *d
amdgpu IRQ 域指针(未使用)
unsigned int irq
虚拟 IRQ 编号
irq_hw_number_t hwirq
硬件 IRQ 编号
描述
当前实现将简单的中断处理程序分配给给定的虚拟 IRQ。
返回
成功时为 0,否则为错误代码
-
int amdgpu_irq_add_domain(struct amdgpu_device *adev)¶
创建线性 IRQ 域
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
为 GPU 中断源创建 IRQ 域,这些中断源可能由另一个驱动程序驱动(例如,ACP)。
返回
成功时为 0,否则为错误代码
-
void amdgpu_irq_remove_domain(struct amdgpu_device *adev)¶
移除 IRQ 域
参数
struct amdgpu_device *adev
amdgpu 设备指针
描述
移除 GPU 中断源的 IRQ 域,这些中断源可能由另一个驱动程序驱动(例如,ACP)。
-
unsigned int amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned int src_id)¶
创建域 Linux IRQ 之间的映射
参数
struct amdgpu_device *adev
amdgpu 设备指针
unsigned int src_id
IH 源 ID
描述
创建域 IRQ(GPU IH src id)和 Linux IRQ 之间的映射。 将其用于生成 GPU 中断但由其他驱动程序驱动的组件(例如,ACP)。
返回
Linux IRQ
IP 块¶
GPU 由 IP(知识产权)块组成。 这些 IP 块提供各种功能:显示、图形、视频解码等。 构成特定 GPU 的 IP 块在 GPU 的相应 SoC 文件中列出。 amdgpu_device.c 在初始化时获取正在使用的 GPU 的 IP 块列表。 然后,它可以对此列表进行操作以执行标准驱动程序操作,例如:初始化、完成、暂停、恢复等。
IP 块实现的命名使用以下约定:<功能>_v<版本>(例如:gfx_v6_0)。
-
enum amd_ip_block_type¶
用于按功能对 IP 块进行分类。
常量
AMD_IP_BLOCK_TYPE_COMMON
GPU 系列
AMD_IP_BLOCK_TYPE_GMC
图形存储器控制器
AMD_IP_BLOCK_TYPE_IH
中断处理程序
AMD_IP_BLOCK_TYPE_SMC
系统管理控制器
AMD_IP_BLOCK_TYPE_PSP
平台安全处理器
AMD_IP_BLOCK_TYPE_DCE
显示和合成引擎
AMD_IP_BLOCK_TYPE_GFX
图形和计算引擎
AMD_IP_BLOCK_TYPE_SDMA
系统 DMA 引擎
AMD_IP_BLOCK_TYPE_UVD
统一视频解码器
AMD_IP_BLOCK_TYPE_VCE
视频压缩引擎
AMD_IP_BLOCK_TYPE_ACP
音频协处理器
AMD_IP_BLOCK_TYPE_VCN
视频核心/编解码器下一代
AMD_IP_BLOCK_TYPE_MES
微引擎调度器
AMD_IP_BLOCK_TYPE_JPEG
JPEG 引擎
AMD_IP_BLOCK_TYPE_VPE
视频处理引擎
AMD_IP_BLOCK_TYPE_UMSCH_MM
多媒体用户模式调度器
AMD_IP_BLOCK_TYPE_ISP
图像信号处理器
AMD_IP_BLOCK_TYPE_NUM
IP 块类型的总数
-
enum DC_DEBUG_MASK¶
可用于调试显示核心 IP 的位
常量
DC_DISABLE_PIPE_SPLIT
如果设置,则禁用管道拆分
DC_DISABLE_STUTTER
如果设置,则禁用内存口吃模式
DC_DISABLE_DSC
如果设置,则禁用显示流压缩
DC_DISABLE_CLOCK_GATING
如果设置,则禁用时钟门控优化
DC_DISABLE_PSR
如果设置,则禁用面板自刷新 v1 和 PSR-SU
DC_FORCE_SUBVP_MCLK_SWITCH
如果设置,则强制在 subvp 中进行 mclk 切换,即使可以在垂直消隐中进行 mclk 切换
DC_DISABLE_MPO
如果设置,则禁用多平面卸载
DC_ENABLE_DPIA_TRACE
如果设置,则为 DPIA 启用跟踪日志记录
DC_ENABLE_DML2
如果设置,则强制使用 DML2,即使 DCN 版本没有默认为此。
DC_DISABLE_PSR_SU
如果设置,则禁用 PSR SU
DC_DISABLE_REPLAY
如果设置,则禁用面板重放
DC_DISABLE_IPS
如果设置,则始终禁用所有空闲电源状态。 如果设置了多个 IPS 调试位,则最低位优先。 例如,如果设置了 DC_FORCE_IPS_ENABLE 和 DC_DISABLE_IPS_DYNAMIC,则 DC_DISABLE_IPS_DYNAMIC 优先。
DC_DISABLE_IPS_DYNAMIC
如果设置,则始终禁用所有 IPS,*除非*驱动程序进入挂起状态。
DC_DISABLE_IPS2_DYNAMIC
如果设置,如果启用了显示器,则禁用 IPS2(允许 IPS1)。 否则,启用所有 IPS。
DC_FORCE_IPS_ENABLE
如果设置,则始终强制启用所有 IPS。
DC_DISABLE_ACPI_EDID
如果设置,则不要尝试从 ACPI _DDC 方法获取 eDP 显示器的 EDID。
DC_DISABLE_HDMI_CEC
如果设置,则禁用 amdgpu 驱动程序中的 HDMI-CEC 功能。
DC_DISABLE_SUBVP_FAMS
如果设置,则禁用 amdgpu 驱动程序中的 DCN 子视口和固件辅助存储时钟切换 (FAMS) 功能。
DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE
如果设置,则禁用对自定义亮度曲线的支持
DC_HDCP_LC_FORCE_FW_ENABLE
如果设置,则使用 HDCP 局部性检查 FW 路径,无论报告的 HW 功能如何。
DC_HDCP_LC_ENABLE_SW_FALLBACK
如果设置,在 HDCP 局部性检查 FW 路径失败时,使用旧版 SW 路径重试。
DC_SKIP_DETECTION_LT
如果设置,则跳过检测链路训练
-
struct amd_ip_funcs¶
用于管理 amdgpu IP 块的通用挂钩
定义:
struct amd_ip_funcs {
char *name;
int (*early_init)(struct amdgpu_ip_block *ip_block);
int (*late_init)(struct amdgpu_ip_block *ip_block);
int (*sw_init)(struct amdgpu_ip_block *ip_block);
int (*sw_fini)(struct amdgpu_ip_block *ip_block);
int (*early_fini)(struct amdgpu_ip_block *ip_block);
int (*hw_init)(struct amdgpu_ip_block *ip_block);
int (*hw_fini)(struct amdgpu_ip_block *ip_block);
void (*late_fini)(struct amdgpu_ip_block *ip_block);
int (*prepare_suspend)(struct amdgpu_ip_block *ip_block);
int (*suspend)(struct amdgpu_ip_block *ip_block);
int (*resume)(struct amdgpu_ip_block *ip_block);
bool (*is_idle)(struct amdgpu_ip_block *ip_block);
int (*wait_for_idle)(struct amdgpu_ip_block *ip_block);
bool (*check_soft_reset)(struct amdgpu_ip_block *ip_block);
int (*pre_soft_reset)(struct amdgpu_ip_block *ip_block);
int (*soft_reset)(struct amdgpu_ip_block *ip_block);
int (*post_soft_reset)(struct amdgpu_ip_block *ip_block);
int (*set_clockgating_state)(struct amdgpu_ip_block *ip_block, enum amd_clockgating_state state);
int (*set_powergating_state)(struct amdgpu_ip_block *ip_block, enum amd_powergating_state state);
void (*get_clockgating_state)(struct amdgpu_ip_block *ip_block, u64 *flags);
void (*dump_ip_state)(struct amdgpu_ip_block *ip_block);
void (*print_ip_state)(struct amdgpu_ip_block *ip_block, struct drm_printer *p);
};
成员
name
IP 块的名称
early_init
设置早期驱动程序状态(sw_init 之前),不配置 hw - 可选
late_init
设置后期驱动程序/hw 状态(hw_init 后)- 可选
sw_init
设置驱动程序状态,不配置 hw
sw_fini
拆卸驱动程序状态,不配置 hw
early_fini
从驱动程序分离 dev 之前拆卸内容
hw_init
设置 hw 状态
hw_fini
拆卸 hw 状态
late_fini
最终清理
prepare_suspend
处理 IP 特定更改以准备挂起(例如,分配任何所需的内存)
suspend
处理 IP 特定 hw/sw 更改以进行挂起
resume
处理 IP 特定 hw/sw 更改以进行恢复
is_idle
返回当前 IP 块空闲状态
wait_for_idle
轮询以确定是否空闲
check_soft_reset
检查软重置 IP 块
pre_soft_reset
预软重置 IP 块
soft_reset
软重置 IP 块
post_soft_reset
后软重置 IP 块
set_clockgating_state
启用/禁用 IP 块的 cg
set_powergating_state
启用/禁用 IP 块的 pg
get_clockgating_state
获取当前时钟门控状态
dump_ip_state
在 GPU 挂起期间转储 ASIC 的 IP 状态
print_ip_state
在 devcoredump 中打印 ASIC 的每个 IP 的 IP 状态
描述
这些挂钩提供了一个接口,用于控制 IP 块的运行状态。 在获取正在使用的 GPU 的 IP 块列表后,驱动程序可以通过遍历此列表并调用每个 IP 块中的挂钩来进行芯片范围的状态更改。 对此列表进行排序,以确保驱动程序以安全的顺序初始化 IP 块。