achnichtsowichtig
achnichtsowichtig

Reputation: 189

How to read instructions retired using the perf-interface inside a LKM?

How can I read from the PMU from inside Kernel space?

For a profiling task I need to read the retired instructions provided by the PMU from inside the kernel. The perf_event_open systemcall seems to offer this capability. In my source code I

#include <linux/syscalls.h>

set my parameters for the perf_event_attr struct and call the sys_perf_event_open(). The mentioned header contains the function declaration. When checking "/proc/kallsyms", it is confirmed that there is a systemcall with the name sys_perf_event_open. The symbol is globally available indicated by the T:

ffffffff8113fe70 T sys_perf_event_open

So everything should work as far as I can tell.

Still, when compiling or inserting the LKM I get a warning/error that sys_perf_event_open does not exist.

WARNING: "sys_perf_event_open" [/home/vagrant/mods/lkm_read_pmu/read_pmu.ko] undefined!

What do I need to do in order to get those retired instructions counter?

Upvotes: 1

Views: 152

Answers (1)

Hadi Brais
Hadi Brais

Reputation: 23729

The /proc/kallsyms file shows all kernel symbols defined in the source. Right, the capital T indicates a global symbol in the text section of the kernel binary, but the meaning of "global" here is according to the C language. That is, it can be used in other files of the kernel itself. You can't call a kernel function from a kernel module just because it's global.

Kernel modules can only use kernel symbols that are exported with EXPORT_SYMBOL in the kernel source code. Since kernel 2.6.0, none of the system calls are exported, so you can't call any of them from a kernel module, including sys_perf_event_open. System calls are really designed to be called from user space. What this all means is that you can't use the perf_event subsystem from within a kernel module.

That said, I think you can modify the kernel to add EXPORT_SYMBOL to sys_perf_event_open. That will make it an exported symbol, which means it can be used from a kernel module.

Upvotes: 2

Related Questions