【问题标题】:How to read PMC(Performance Monitoring Counter) of x86 intel processor如何读取 x86 intel 处理器的 PMC(Performance Monitoring Counter)
【发布时间】:2020-07-08 19:57:00
【问题描述】:

我的桌面是带有 Ubuntu 操作系统的 Intel x86_64 处理器。

我知道有 perf 工具可以获取程序的统计信息列表。 但我想做的是直接读取性能计数器而不使用 perf 工具。

  1. 第一个问题

第一个问题是我从 Github 下载了这段代码:Github Code Reference。

它使用 linux-headers-5.3.0-40-generic 内核成功编译,没有任何错误。一旦我使用“insmod”.ko 文件,系统就会挂起。检查 dmesg 时未插入 .ko 文件,因此在对 .ko 文件执行“insmod”后必须停止它。发生这种情况是因为我尝试了未经授权的访问吗?如果有我可以尝试的建议,我很高兴听到。

对应的代码如下。

static void set_pce(void *arg)
{
    int to_val = (arg != 0);
    u_int64_t cr4_val;

    cr4_val = __read_cr4();
    if (to_val) {
        cr4_val |= X86_CR4_PCE;
    } else {
        cr4_val &= ~X86_CR4_PCE;
    }

    __write_cr4(cr4_val);
}

static int __init user_rdpmc_init(void){
    int cpu;

    num_cpus = num_online_cpus();

    printk(KERN_INFO "Enabling RDPMC from ring 3 for %d CPUs\n", num_cpus);
    for (cpu = 0; cpu < num_cpus; cpu++) {
    smp_call_function_single(cpu, set_pce, (void *) 1, 1);
    }

   return 0;
}
  1. 第二个问题

第二个问题是我在我的 Ubuntu 桌面上使用 linux-headers-5.3.0-40-generic 内核版本。我从 kernel.org 下载了内核代码版本 5.5.3。我彻底遵循了 5.5.3 内核代码中给出的 perf 代码,发现 linux-5.5.3/arch/x86/events/intel 目录下的 core.c 文件实际上是在设置和读取性能计数器。我使用 core.c 文件内容将其作为模块来读取性能计数器。当我编译它时,它会产生一堆错误,因为我使用 linux-headers-5.3.0-40-generic 来构建模块,但是我的 ubuntu 内核没有从内核代码链接到 core.c 文件的所有头文件来自 kernel.org。

如何让我的 Ubuntu 内核使用从 kernel.org 链接到 core.c 的所有文件并构建 .ko 文件?

或者是否有任何具有 x86 性能计数器读数的模块源代码可以用作参考?

提前感谢您的帮助。

【问题讨论】:

标签: linux-kernel x86-64 kernel-module perf intel-pmu


【解决方案1】:

我知道有 perf 工具可以获取程序的统计信息列表。但我想做的是直接读取性能计数器而不使用 perf 工具。

如果不想使用perf工具,可以尝试使用oprofile工具或者intel vtune或者https://github.com/RRZE-HPC/likwid或者https://github.com/opcm/pcm。或者您可以使用perf_event_open syscall,这就是 perf 工具的工作原理(您可以从 https://mirrors.edge.kernel.org/pub/linux/kernel/tools/perf/ 学习或修改 perf 工具源 - 并且 perf 工具版本可能不等于内核版本)。

如果您想以 root 身份访问 msr 寄存器,请使用 modprobe msr(这是 standard kernel module,已在 ubuntu 中为您的内核编译)和 wrmsr 和 rdmsr 工具(msr-tools deb/ubuntu 包,@ 987654327@),如Performance Monitoring Chris Dahnken Intel SSG EMEA HPCTC 演示文稿的第 27 张幻灯片中所示。

我不明白您为什么要在没有性能工具的情况下使用性能计数器。如果您想从程序内部获取计数器读数,例如在某些循环之前和之后,您可以直接使用perf_event_open syscall(带有特定的 ioctls)。 (或尝试使用perf stat + 相同的ioctls PERF_EVENT_IOC_* 或尝试学习perf + JIT 集成)

或者您可以使用现有的内核模块,它将 msr 注册访问权限导出给 root 用户 - the msr.ko。还有 msr 工具 - https://01.org/msr-tools。或者使用这个 msr+pmc 示例 https://technicalandstuff.wordpress.com/2015/05/15/using-intels-pcm-in-linux-and-inside-c/ + https://software.intel.com/en-us/articles/intel-performance-counter-monitor (https://github.com/opcm/pcm)

https://github.com/RRZE-HPC/likwid 中还有一些性能计数器使用示例。

您还可以使用PAPI library 从您的代码中访问计数器,它将为您处理大部分 perf_event_open 内容。 http://icl.cs.utk.edu/projects/papi/wiki/PAPITopics:Getting_Started

第一个问题是我下载了这个代码https://github.com/softdevteam/user_rdpmc ... "insmod" .ko 文件,系统挂起。

“星级”评级太低,代码太旧(2016 年),无法真正对挂起进行任何调查。直接访问 PMC 可能会干扰 NMI 看门狗(以 root 身份执行 echo 0 &gt; /proc/sys/kernel/nmi_watchdog)或其他 perf 会话。使用 perf_event_open 系统调用更安全。

第二个问题...发现linux-5.5.3/arch/x86/events/intel目录下的core.c文件实际上是在设置和读取性能计数器

此文件是 perf_event_open 系统调用实现的一部分(内核的 perf_events 子系统,https://github.com/torvalds/linux/tree/master/kernel/events + https://github.com/torvalds/linux/tree/master/arch/x86/events)。

要使用此代码,您可以使用perf 工具或 perf_event_open 系统调用。

您不应该将内核的 perf_events 子系统编译为单独的模块,因为它已经编译到您的内核中(intel/amd 特定部分可以部分 ko)并且子系统本身不支持编译为模块:

https://github.com/torvalds/linux/tree/master/kernel/events

Makefile: obj-y := core.o ring_buffer.o callchain.o

如何让我的 Ubuntu 内核使用从 kernel.org 链接到 core.c 的所有文件并构建 .ko 文件?

您的 ubuntu 内核已经编译了所有 perf_events 子系统文件,其中一些链接到内核映像中,其他是已安装的 .ko 文件,如 intel-rapl-perf.ko

$ grep _PERF_ /boot/config-`uname -r`
$ ls -l /lib/modules/`uname -r`/kernel/arch/x86/events/intel

【讨论】:

  • 感谢您提供的详细信息和一些我可以查看的资源。出于研究目的,我需要在没有 perf 工具的情况下读取性能计数器,所以我无法说出我需要它的确切原因。我会尝试你给我的建议,如果我还有更多要问的,我会进一步询问。我真的很感激。
猜你喜欢
  • 2018-08-17
  • 1970-01-01
  • 2010-10-17
  • 2018-05-05
  • 1970-01-01
  • 2017-08-07
  • 2010-12-11
  • 2010-10-06
  • 2020-05-24
相关资源
最近更新 更多