Discussion:
Logging PMU counters during context switch
Guru Prasad
2014-01-10 05:59:48 UTC
Permalink
Architecture: ARM
CPU: Cortex-A9

Hi,
My goal is to log PMU counters during context switches.

Is there any documentation available in kernel on how to use perf
functions within the kernel itself?
I'm having a lot of difficulty setting up struct perf_event from
within the kernel.

What I currently have is the following

#ifdef CONFIG_PERIODIC_PMU_LOG
if(unlikely(!initialize_pmu_log)) {
unsigned int value;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (value));
//Read PMCR register
value |= 0x00000005; //Set reset-PMCCNTR-bit and enable-bit
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (value));
//Write PMCR register

asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (value));
//Read PMCNTENSET
value |= 0x80000000; //Set cycle counter enable
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (value));
//Write PMCNTENSET
initialize_pmu_log = 1;
}
else {
unsigned int value;
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
//Read PMCCNTR
printk(KERN_DEBUG "periodic_perf: PMCCNTR :%u\n", value);
}
#endif


This works..for a while..however, at some point, the counter just
hangs at an arbitrary value relatively close to 2^32 - 1 (example
0xBFB69F7F)
and sometimes it alternates between 2~3 values..in my last run, these were
0xBEB49F3B
0xBEB69F3B
0xBFB69F7F

Is this somehow because of overflows?
I also tried adding an extra line to the initialization condition to
disable cycle counter interrupt in PMINTENCLR but this did not help..
value = 0x800000000
asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (value));


Regards
Guru
Vince Weaver
2014-01-10 14:10:22 UTC
Permalink
Post by Guru Prasad
Architecture: ARM
CPU: Cortex-A9
Hi,
My goal is to log PMU counters during context switches.
Is there any documentation available in kernel on how to use perf
functions within the kernel itself?
I'm having a lot of difficulty setting up struct perf_event from
within the kernel.
someone's probably going to chime in and say you can do this from
userspace using the right combination of ftrace events (or could you
even do it setting overflow on the software context switch event with
a frequency of 1?)

In any case I wouldn't reccommend poking the PMU registers directly in a
kernel that has perf_event running. Reading them is probably OK but
writing them is just going to confuse things. Can you not set up and
start the counters from userspace and then just have your printing code in
the kernel print things (without touching the registers?)

Vince Weaver
***@maine.edu
http://www.eece.maine.edu/~vweaver/

Loading...