diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-12-14 21:26:40 +0100 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-12-16 11:36:44 +0100 | 
| commit | 7639dae0ca11038286bbbcda05f2bef601c1eb8d (patch) | |
| tree | 5cfcea4ea730cf255c6fb960577083f17c876377 | |
| parent | abe43400579d5de0078c2d3a760e6598e183f871 (diff) | |
| download | olio-linux-3.10-7639dae0ca11038286bbbcda05f2bef601c1eb8d.tar.xz olio-linux-3.10-7639dae0ca11038286bbbcda05f2bef601c1eb8d.zip  | |
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>
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 26 | 
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index c8f5c088cad..24e390e40f2 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -816,6 +816,32 @@ static int intel_pmu_hw_config(struct perf_event *event)  	if (ret)  		return ret; +	if (event->attr.precise_ip && +	    (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { +		/* +		 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P +		 * (0x003c) so that we can use it with PEBS. +		 * +		 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't +		 * PEBS capable. However we can use INST_RETIRED.ANY_P +		 * (0x00c0), which is a PEBS capable event, to get the same +		 * count. +		 * +		 * INST_RETIRED.ANY_P counts the number of cycles that retires +		 * CNTMASK instructions. By setting CNTMASK to a value (16) +		 * larger than the maximum number of instructions that can be +		 * retired per cycle (4) and then inverting the condition, we +		 * count all cycles that retire 16 or less instructions, which +		 * is every cycle. +		 * +		 * Thereby we gain a PEBS capable cycle counter. +		 */ +		u64 alt_config = 0x108000c0; /* INST_RETIRED.TOTAL_CYCLES */ + +		alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); +		event->hw.config = alt_config; +	} +  	if (event->attr.type != PERF_TYPE_RAW)  		return 0;  |