DRM 客户端使用统计¶
DRM 驱动程序可以选择通过 fops->show_fdinfo() 导出部分标准化的文本输出,作为在 DRM 核心中注册的 struct drm_driver
对象中注册的驱动程序特定文件操作的一部分。
此输出的一个目的是使编写尽可能通用的 top(1) 类用户空间监控工具成为可能。
鉴于各种 DRM 驱动程序之间的差异,输出的规范分为通用部分和驱动程序特定部分。话虽如此,应尽可能努力标准化尽可能多的内容。
文件格式规范¶
文件每行应包含一个键值对。
冒号字符(:)必须用于分隔键和值。
所有键都应以 drm- 为前缀。
在解析时,分隔符和第一个非空白字符之间的空格应被忽略。
键不允许包含空格字符。
数值键值对可以以可选的单位字符串结尾。
值的 数据类型在规范中定义为固定的。
键类型¶
强制性的,完全标准化。
可选的,完全标准化。
驱动程序特定的。
数据类型¶
<uint> - 无符号整数,不定义最大值。
<keystr> - 字符串,不包括任何上述定义的保留字符或空格。
<valstr> - 字符串。
强制性的完全标准化键¶
drm-driver: <valstr>
字符串应包含此驱动程序通过各自的 struct drm_driver
数据结构注册的名称。
可选的完全标准化键¶
标识¶
drm-pdev: <aaaa:bb.cc.d>
对于 PCI 设备,这应包含相关设备的 PCI 插槽地址。
drm-client-id: <uint>
与打开的 DRM 文件描述符相关的唯一值,用于区分重复和共享的文件描述符。从概念上讲,该值应与内核中 struct drm_file
实例的表示形式 1:1 映射。
该值的唯一性应为全局唯一,或在每个设备的范围内唯一,在这种情况下,也应存在 drm-pdev。
用户空间应确保不通过使用上述标准将数据与各个客户端相关联来重复计算任何使用统计信息。
drm-client-name: <valstr>
用户空间使用 DRM_IOCTL_SET_CLIENT_NAME 可选设置的字符串。
利用率¶
drm-engine-<keystr>: <uint> ns
GPU 通常包含多个执行引擎。每个引擎都应给定一个稳定且唯一的名称(keystr),可能的值记录在驱动程序特定的文档中。
该值应为指定的单位时间,即各个 GPU 引擎忙于执行属于此客户端的工作负载所花费的时间。
如果这样可以使驱动程序实现更简单,则值不需要始终单调,但需要在合理的时间内赶上先前报告的较大值。观察到低于先前读取的值时,用户空间应保持该较大的先前值,直到看到单调更新。
drm-engine-capacity-<keystr>: <uint>
引擎标识符字符串必须与 drm-engine-<keystr> 标签中指定的字符串相同,并且如果导出的引擎对应于一组相同的硬件引擎,则应包含一个大于零的数字。
如果缺少此标签,则解析器应假定容量为 1。不允许容量为零。
drm-cycles-<keystr>: <uint>
引擎标识符字符串必须与 drm-engine-<keystr> 标签中指定的字符串相同,并且应包含给定引擎的繁忙周期数。
如果这样可以使驱动程序实现更简单,则值不需要始终单调,但需要在合理的时间内赶上先前报告的较大值。观察到低于先前读取的值时,用户空间应保持该较大的先前值,直到看到单调更新。
drm-total-cycles-<keystr>: <uint>
引擎标识符字符串必须与 drm-cycles-<keystr> 标签中指定的字符串相同,并且应包含给定引擎的总周期数。
这是一个以 GPU 未指定单位表示的时间戳,与 drm-cycles-<keystr> 的更新速率匹配。对于实现此接口的驱动程序,引擎利用率可以完全在 GPU 时钟域上计算,而无需考虑 2 个样本之间 CPU 的睡眠时间。
驱动程序可以实现此键或 drm-maxfreq-<keystr>,但不能同时实现两者。
drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz]
引擎标识符字符串必须与 drm-engine-<keystr> 标签中指定的字符串相同,并且应包含给定引擎的最大频率。结合 drm-cycles-<keystr>,这可以用于计算引擎的百分比利用率,而 drm-engine-<keystr> 仅反映活动时间,而没有考虑引擎以最大频率的百分比运行的频率。
驱动程序可以实现此键或 drm-total-cycles-<keystr>,但不能同时实现两者。
内存¶
drm-memory-<region>: <uint> [KiB|MiB]
可以用来存储相关 GPU 的缓冲对象的每种可能的内存类型都应给出一个稳定且唯一的名称,作为此处返回的字符串。
区域名称 “memory” 保留用于引用正常的系统内存。
该值应反映此客户端拥有的缓冲对象当前在相应内存区域中消耗的存储量。
默认单位应为字节,带有可选的单位指定符“KiB”或“MiB”,表示千比字节或兆比字节。
此键已弃用,是 drm-resident-<region> 的别名。输出中只能存在其中一个。
drm-shared-<region>: <uint> [KiB|MiB]
与其他文件共享的缓冲区总大小(例如,具有多个句柄)。
drm-total-<region>: <uint> [KiB|MiB]
所有已创建缓冲区的总大小,包括共享内存和私有内存。缓冲区的后备存储不需要当前被实例化才能在此类别下计数。
drm-resident-<region>: <uint> [KiB|MiB]
在指定区域中驻留(具有其后备存储存在或实例化)的缓冲区总大小。
这是 drm-memory-<region> 的别名,输出中只能存在其中一个。
drm-purgeable-<region>: <uint> [KiB|MiB]
可清除的缓冲区总大小。
例如,实现某种形式的“madvise”类功能的驱动程序可以在此处计算已实例化后备存储,但已标记为 MADV_DONTNEED 等效项的缓冲区。
drm-active-<region>: <uint> [KiB|MiB]
在一个或多个引擎上处于活动状态的缓冲区总大小。
一个实际示例可以是 GEM 缓冲区预留对象中是否存在未发出信号的栅栏。因此,活动类别是驻留类别的子集。
实现细节¶
驱动程序应在其 struct file_operations 中使用 drm_show_fdinfo()
,并且如果他们希望提供 drm_show_fdinfo()
未提供的任何统计信息,则实现 &drm_driver.show_fdinfo。但是,即使是特定于驱动程序的统计信息也应在上面记录,并在可能的情况下与其他驱动程序保持一致。