读取PMCCNTR_EL0的访问频率限制?

问题描述 投票:0回答:1

我在我的 c 分析应用程序中使用

perf_event_open
来利用 perf 来获取事件数据。为了提高性能,我直接读取硬件寄存器,按照Perf Userspace PMU Hardware Counter Access Documentation使用
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);
uint64_t read_register_directly() {
  uint64_t value = 0;
  asm volatile("mrs %0, PMCCNTR_EL0 " : "=r" (value));
  return value;
}

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

  • 会不会是访问频率限制?
  • 或者一些ARM安全机制?
  • 也许存在一些并发问题?尽管我通过使用信号量锁定 read_register_directly() 来测试这一点以确保一次读取一次,但问题仍然存在。

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

c arm profiling perf
1个回答
0
投票

这最终是由于在

perf_event_open
系统调用中传递的属性造成的。进行系统调用的线程能够直接读取寄存器,但其他线程导致“非法指令”错误。

有一个

perf_event_attr
标志
inherit
,它允许用户分析进程中的所有线程,而不仅仅是由
perf_event_open
执行的线程。所以在上面的代码中我添加了两件事来修复代码流程:

  • attr.inherit = 1;
  • asm volatile("isb;");
    读取PMU寄存器后
© www.soinside.com 2019 - 2024. All rights reserved.