Perf¶
Perf 事件属性¶
- 作者:
Andrew Murray <andrew.murray@arm.com>
- 日期:
2019-03-06
exclude_user¶
此属性排除用户空间。
用户空间始终在 EL0 运行,因此此属性将排除 EL0。
exclude_kernel¶
此属性排除内核。
内核在 EL2(使用 VHE)和 EL1(不使用 VHE)运行。客户机内核始终在 EL1 运行。
对于宿主机,此属性将排除 EL1,并且在使用 VHE 系统的同时排除 EL2。
对于客户机,此属性将排除 EL1。请注意,EL2 永远不会在客户机中被计数。
exclude_hv¶
此属性排除 Hypervisor。
对于 VHE 宿主机,此属性将被忽略,因为我们认为宿主机内核是 Hypervisor。
对于非 VHE 宿主机,此属性将排除 EL2,因为我们认为 Hypervisor 是任何在 EL2 运行的代码,主要用于客户机/宿主机之间的转换。
对于客户机,此属性无效。请注意,EL2 永远不会在客户机中被计数。
exclude_host / exclude_guest¶
这些属性分别排除 KVM 宿主机和客户机。
KVM 宿主机可以在 EL0(用户空间)、EL1(非 VHE 内核)和 EL2(VHE 内核或非 VHE Hypervisor)运行。
KVM 客户机可以在 EL0(用户空间)和 EL1(内核)运行。
由于宿主机和客户机之间的异常级别重叠,我们不能完全依赖 PMU 的硬件异常过滤 - 因此我们必须在进入和退出客户机时启用/禁用计数。这在 VHE 和非 VHE 系统上的执行方式不同。
对于非 VHE 系统,我们为 exclude_host 排除 EL2 - 在进入和退出客户机时,我们根据 exclude_host 和 exclude_guest 属性禁用/启用相应的事件。
对于 VHE 系统,我们为 exclude_guest 排除 EL1,并为 exclude_host 同时排除 EL0 和 EL2。在进入和退出客户机时,我们根据 exclude_host 和 exclude_guest 属性修改事件以包含/排除 EL0。
当这些属性在非 VHE 客户机中使用时,上述语句也适用,但请注意,EL2 永远不会在客户机中被计数。
精度¶
在非 VHE 宿主机上,我们在 EL2 的宿主机/客户机转换的入口/出口处启用/禁用计数器 - 但是在启用/禁用计数器和进入/退出客户机之间存在一段时间。通过为 exclude_host 过滤 EL2,我们可以在计数客户机事件时消除在客户机入口/出口边界上计数宿主机事件的计数器。但是,当使用 !exclude_hv 时,在客户机入口/出口处存在一个小的黑屏窗口,其中宿主机事件不会被捕获。
在 VHE 系统上,没有黑屏窗口。
Perf 用户空间 PMU 硬件计数器访问¶
概述¶
perf 用户空间工具依赖 PMU 来监视事件。它在硬件计数器上提供了一个抽象层,因为底层实现是 CPU 相关的。Arm64 允许用户空间工具直接访问存储硬件计数器值的寄存器。
这专门针对自我监视任务,以便通过直接访问寄存器来减少开销,而无需通过内核。
操作方法¶
重点放在 armv8 PMUv3 上,它确保启用了对 pmu 寄存器的访问,并且用户空间可以访问相关信息以便使用它们。
为了访问硬件计数器,必须首先启用全局 sysctl kernel/perf_user_access
echo 1 > /proc/sys/kernel/perf_user_access
必须使用 perf 工具接口打开事件,并设置 config1:1 属性位:sys_perf_event_open 系统调用返回一个 fd,该 fd 可以随后与 mmap 系统调用一起使用,以便检索包含有关事件信息的内存页。PMU 驱动程序使用此页面向用户公开硬件计数器的索引和其他必要数据。使用此索引允许用户使用 mrs 指令访问 PMU 寄存器。只有在序列锁未更改时,对 PMU 寄存器的访问才有效。特别是,每次序列锁更改时,PMSELR_EL0 寄存器都会被置零。
libperf 中使用 perf_evsel__mmap() 和 perf_evsel__read() 函数支持用户空间访问。有关示例,请参阅tools/lib/perf/tests/test-evsel.c。
关于异构系统¶
在像 big.LITTLE 这样的异构系统上,只有当任务被固定到同质核心子集并且通过指定“类型”属性打开相应的 PMU 实例时,才能启用用户空间 PMU 计数器访问。在这种情况下不支持使用通用事件类型。
请参阅 tools/perf/arch/arm64/tests/user-events.c 以获取示例。可以使用 perf 工具运行它,以检查从用户空间访问寄存器是否正常工作
perf test -v user
关于链接事件和计数器大小¶
用户可以请求 32 位 (config1:0 == 0) 或 64 位 (config1:0 == 1) 计数器以及用户空间访问。如果请求 64 位计数器且硬件不支持 64 位计数器,则 sys_perf_event_open 系统调用将失败。链接事件不支持与用户空间计数器访问结合使用。如果在具有 64 位计数器的硬件上请求 32 位计数器,则用户空间必须将从计数器读取的较高 32 位视为 UNKNOWN。用户页面中的 'pmc_width' 字段将指示计数器的有效宽度,应使用该宽度来根据需要屏蔽高位。
事件计数阈值¶
概述¶
FEAT_PMUv3_TH (Armv8.8) 允许 PMU 计数器仅在事件计数满足指定阈值条件时递增。例如,如果 threshold_compare 设置为 2(“大于或等于”),并且阈值设置为 2,则 PMU 计数器现在仅当事件先前在单个处理器周期上将 PMU 计数器递增 2 或更多时才会递增。
要在通过阈值条件后递增 1 而不是该周期上的事件数,请将 'threshold_count' 选项添加到命令行。
操作方法¶
以下是用于控制该功能的参数
参数 |
描述 |
---|---|
threshold |
用于设置事件阈值的值。值为 0 表示禁用阈值,并且其他参数无效。 |
threshold_compare |
要使用的比较函数,支持以下值
0:不等于
1:等于
2:大于或等于
3:小于
|
threshold_count |
如果设置此项,则在通过阈值条件后递增 1,而不是此周期上的事件值。 |
可以为每个事件提供 threshold、threshold_compare 和 threshold_count 值,例如
perf stat -e stall_slot/threshold=2,threshold_compare=2/ \
-e dtlb_walk/threshold=10,threshold_compare=3,threshold_count/
在此示例中,stall_slot 事件将在每次发生 2 个或更多停顿时,每个周期计数 2 个或更多。并且 dtlb_walk 将在每次 dtlb 步数小于 10 时,每个周期计数 1。
可以从每个 PMU 的上限读取支持的最大阈值,例如
cat /sys/bus/event_source/devices/armv8_pmuv3/caps/threshold_max
0x000000ff
如果给定的值高于此值,则打开事件将导致错误。最高可能的最大值为 4095,因为阈值的配置字段限制为 12 位,并且 Perf 工具将拒绝解析更高的值。
如果 PMU 不支持 FEAT_PMUv3_TH,则 threshold_max 将读取为 0,并且尝试设置阈值也会导致错误。即使主机运行在具有该功能的硬件上,threshold_max 在 aarch32 客户机上也将读取为 0。