Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf, x86: Provide a PEBS capable cycle event

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Peter Zijlstra and committed by
Ingo Molnar
7639dae0 abe43400

+26
+26
arch/x86/kernel/cpu/perf_event_intel.c
··· 816 816 if (ret) 817 817 return ret; 818 818 819 + if (event->attr.precise_ip && 820 + (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { 821 + /* 822 + * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P 823 + * (0x003c) so that we can use it with PEBS. 824 + * 825 + * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't 826 + * PEBS capable. However we can use INST_RETIRED.ANY_P 827 + * (0x00c0), which is a PEBS capable event, to get the same 828 + * count. 829 + * 830 + * INST_RETIRED.ANY_P counts the number of cycles that retires 831 + * CNTMASK instructions. By setting CNTMASK to a value (16) 832 + * larger than the maximum number of instructions that can be 833 + * retired per cycle (4) and then inverting the condition, we 834 + * count all cycles that retire 16 or less instructions, which 835 + * is every cycle. 836 + * 837 + * Thereby we gain a PEBS capable cycle counter. 838 + */ 839 + u64 alt_config = 0x108000c0; /* INST_RETIRED.TOTAL_CYCLES */ 840 + 841 + alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); 842 + event->hw.config = alt_config; 843 + } 844 + 819 845 if (event->attr.type != PERF_TYPE_RAW) 820 846 return 0; 821 847