阅读PMCCNTR_EL0的访问频率限制?

ukxgm1gy  于 2024-01-06  发布在  其他
关注(0)|答案(1)|浏览(142)

我在我的c profiling应用程序中使用perf_event_open来利用perf获取事件数据。为了提高性能,我直接阅读硬件寄存器,按照Perf Userspace PMU Hardware Counter Access文档使用mrs指令直接读取PMU寄存器。
我使用以下代码:

static struct perf_event_attr attr;
attr.type = PERF_TYPE_HARDWARE;
attr.config = PERF_COUNT_HW_CPU_CYCLES;
attr.exclude_kernel = 1;
attr.exclude_hv = 1;
attr.config1 = 3; // user access enabled

int fd = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0);

ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

// Code where we want to measure performance. At certain points we call read_register_directly()

ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
close(fd);

个字符
上面直接读取寄存器的代码在perf配置下可以正常工作。问题是在读了大约25次寄存器后,我得到了一个“非法指令”错误,尽管我不知道为什么。

  • 会不会是访问频率限制?
  • 或者是ARM安全机制?
  • 可能是并发问题?虽然我使用信号量来锁定read_register_directly()以确保一次只读一次,但这个问题仍然存在。

我查看了PMCCNTR_EL0和其他一些资源的ARM文档,但我没有找到任何可以解释这个非法指令错误的东西。

kuuvgm7e

kuuvgm7e1#

这最终是由于perf_event_open系统调用中传递的属性。进行系统调用的线程能够直接读取寄存器,但其他线程导致“非法指令”错误。
有一个perf_event_attr标志inherit,它允许用户分析进程中的所有线程,而不仅仅是perf_event_open执行的线程。所以在上面的代码中,我添加了两件事来修复代码流:

  • attr.inherit = 1;
  • 阅读PMU寄存器后的asm volatile("isb;");

相关问题