3

我的桌面是带有 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 性能计数器读数的模块源代码可以用作参考?

提前谢谢你的帮助。

4

1 回答 1

3

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

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

如果您想以 root 身份访问 msr 寄存器,请使用modprobe msr(这是标准内核模块,已在 ubuntu 中为您的内核编译)wrmsrrdmsr工具(msr-tools deb /ubuntu 包,由 intel提供),如Performance Monitoring Chris的幻灯片 27 Dahnken 英特尔 SSG EMEA HPCTC演示文稿。

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

或者您可以使用现有的内核模块,它将 msr 注册访问权限导出给 root 用户- 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 库从您的代码中访问计数器,它将为您处理大部分 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 看门狗(echo 0 > /proc/sys/kernel/nmi_watchdog以 root 身份执行)或其他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/事件)。

要使用此代码,您可以使用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
于 2020-03-31T09:57:41.520 回答