我想阅读某些性能计数器。我知道有像 perf 这样的工具,可以在用户空间本身为我做这件事,我希望代码在 Linux 内核中。
我想编写一种机制来监视 Intel(R) Core(TM) i7-3770 CPU 上的性能计数器。除了使用之外,我还使用 Ubuntu 内核 4.19.2。我从easyperf得到了以下方法
这是我阅读说明的代码的一部分。
struct perf_event_attr *attr
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof (struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 0;
pe.exclude_kernel = 0;
pe.exclude_user = 0;
pe.exclude_hv = 0;
pe.exclude_idle = 0;
fd = syscall(__NR_perf_event_open, hw, pid, cpu, grp, flags);
uint64_t perf_read(int fd) {
uint64_t val;
int rc;
rc = read(fd, &val, sizeof(val));
assert(rc == sizeof(val));
return val;
}
我想将相同的行放在内核代码中(在上下文切换函数中)并检查正在读取的值。
我的最终目标是找出一种方法来读取进程的性能计数器,每次它从内核(4.19.2)本身切换到另一个时。
为此,我查看了系统调用号 __NR_perf_event_open 的代码。它可以在这里找到 为了使其可用,我将其中的代码复制为一个单独的函数,在同一个文件中将其命名为 perf_event_open() 并导出。
现在的问题是每当我以与上面相同的方式调用 perf_event_open() 时,返回的描述符都是-2。检查错误代码,我发现错误是 ENOENT。在perf_event_open() 手册页中,此错误的原因被定义为错误类型字段。
由于文件描述符与打开它们的进程相关联,如何从内核中使用它们?是否有另一种方法可以将 pmu 配置为在不涉及文件描述符的情况下开始计数?