gpt4 book ai didi

c - 使用 wrmsrl 和 rdmsrl 读取 PMU 计数器

转载 作者:行者123 更新时间:2023-12-05 02:29:26 25 4
gpt4 key购买 nike

我正在尝试读取 Intel Xeon gold(Skylake 一代)处理器上 Linux 内核模块中的 LLC 缓存未命中硬件计数器。以下代码的结果始终为零:

#define PMC_ESEL_UMASK_SHIFT 8
#define PMC_ESEL_CMASK_SHIFT 24

#define PMC_ESEL_ENTRY(event, umask, cmask) \
(((event)&0xFFUL) | \
(((umask)&0xFFUL) << PMC_ESEL_UMASK_SHIFT) | \
(((cmask)&0xFFUL) << PMC_ESEL_CMASK_SHIFT))

#define PMC_ESEL_USR (1ULL << 16) /* User Mode */
#define PMC_ESEL_OS (1ULL << 17) /* Kernel Mode */
#define PMC_ESEL_EDGE (1ULL << 18) /* Edge detect */
#define PMC_ESEL_PC (1ULL << 19) /* Pin control */
#define PMC_ESEL_INT (1ULL << 20) /* APIC interrupt enable */
#define PMC_ESEL_ANY (1ULL << 21) /* Any thread */
#define PMC_ESEL_ENABLE (1ULL << 22) /* Enable counters */
#define PMC_ESEL_INV (1ULL << 23) /* Invert counter mask */

/* architectural performance counters (works on all Intel CPUs) */
#define PMC_ARCH_CORE_CYCLES PMC_ESEL_ENTRY(0x3C, 0x00, 0)
#define PMC_ARCH_INSTR_RETIRED PMC_ESEL_ENTRY(0xC0, 0x00, 0)
#define PMC_ARCH_REF_CYCLES PMC_ESEL_ENTRY(0x3C, 0x01, 0)
#define PMC_ARCH_LLC_REF PMC_ESEL_ENTRY(0x2E, 0x4F, 0)
#define PMC_ARCH_LLC_MISSES PMC_ESEL_ENTRY(0x2E, 0x41, 0)
#define PMC_ARCH_BRANCHES PMC_ESEL_ENTRY(0xC4, 0x00, 0)
#define PMC_ARCH_BRANCH_MISSES PMC_ESEL_ENTRY(0xC5, 0x00, 0)

#define PMC_LLC_MISSES (PMC_ARCH_LLC_MISSES | PMC_ESEL_USR | PMC_ESEL_OS | \
PMC_ESEL_ENABLE)
#define PMC_LLC_MISSES_ANY (PMC_ARCH_LLC_MISSES | PMC_ESEL_USR | PMC_ESEL_OS | \
PMC_ESEL_ANY | PMC_ESEL_ENABLE)

/* enable/disable perf counter */
#define CORE_PERF_GLOBAL_CTRL_ENABLE_PMC_0 (0x1)
#define CORE_PERF_GLOBAL_CTRL_ENABLE_PMC_1 (0x2)

void test(void)
{
u64 val;
wrmsrl(MSR_CORE_PERF_FIXED_CTR_CTRL, 0x333);
wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
CORE_PERF_GLOBAL_CTRL_ENABLE_PMC_0 |
CORE_PERF_GLOBAL_CTRL_ENABLE_PMC_1 |
(1UL << 32) | (1UL << 33) | (1UL << 34));
wrmsrl(MSR_P6_EVNTSEL0, PMC_LLC_MISSES);
rdmsrl(MSR_P6_PERFCTR0, val);
printk(KERN_DEBUG "The LLC-Miss value is: %llu\n", val);
}

任何人都可以帮助解决此代码的问题吗?

最佳答案

我似乎错过了使用 rdmsrl_on_corewrmsrl_on_cpu 在每个内核上启用和读取 PMC。我附上了内核模块代码的工作版本,以防将来有人需要它:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mohammad Siavashi");
MODULE_DESCRIPTION("A sample LLC miss counter reader");

#define IA32_PERF_GLOBAL_CTRL_ENABLE 0x70000000f
#define LLC_EVENT 0x0043412e
#define IA32_PERF_FIXED_CTRL_ENABLE 0x333

static int __init hello_init(void)
{
int cpu;
wrmsrl(MSR_CORE_PERF_FIXED_CTR_CTRL, IA32_PERF_FIXED_CTRL_ENABLE);
wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, IA32_PERF_GLOBAL_CTRL_ENABLE);
for_each_possible_cpu(cpu)
{
wrmsrl_on_cpu(cpu, MSR_P6_EVNTSEL0, LLC_EVENT);
}
return 0;
}

static void __exit hello_cleanup(void)
{
int cpu;
u64 val;
for_each_possible_cpu(cpu)
{
rdmsrl_on_cpu(cpu, MSR_IA32_PERFCTR0, &val);
printk(KERN_DEBUG "The LLC-Miss on core %i is: %llu\n", cpu, val);
}
printk(KERN_INFO "Cleaning up module.\n");
}

module_init(hello_init);
module_exit(hello_cleanup);

关于c - 使用 wrmsrl 和 rdmsrl 读取 PMU 计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72177614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com