aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2013-06-25 11:12:33 -0400
committerIngo Molnar <mingo@kernel.org>2013-06-26 05:59:25 -0400
commit069e0c3c405814778c7475d95b9fff5318f39834 (patch)
tree7fa205dc1bfa0ba7cbb8c421b7b9d10741b655a6
parent0c4df02d739fed5ab081b330d67403206dd3967e (diff)
perf/x86/intel: Support full width counting
Recent Intel CPUs like Haswell and IvyBridge have a new alternative MSR range for perfctrs that allows writing the full counter width. Enable this range if the hardware reports it using a new capability bit. Currently the perf code queries CPUID to get the counter width, and sign extends the counter values as needed. The traditional PERFCTR MSRs always limit to 32bit, even though the counter internally is larger (usually 48 bits on recent CPUs) When the new capability is set use the alternative range which do not have these restrictions. This lowers the overhead of perf stat slightly because it has to do less interrupts to accumulate the counter value. On Haswell it also avoids some problems with TSX aborting when the end of the counter range is reached. ( See the patch "perf/x86/intel: Avoid checkpointed counters causing excessive TSX aborts" for more details. ) Signed-off-by: Andi Kleen <ak@linux.intel.com> Reviewed-by: Stephane Eranian <eranian@google.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1372173153-20215-1-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/uapi/asm/msr-index.h3
-rw-r--r--arch/x86/kernel/cpu/perf_event.h5
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c7
3 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
index 2af848dfa754..bb0465090ae5 100644
--- a/arch/x86/include/uapi/asm/msr-index.h
+++ b/arch/x86/include/uapi/asm/msr-index.h
@@ -170,6 +170,9 @@
170#define MSR_KNC_EVNTSEL0 0x00000028 170#define MSR_KNC_EVNTSEL0 0x00000028
171#define MSR_KNC_EVNTSEL1 0x00000029 171#define MSR_KNC_EVNTSEL1 0x00000029
172 172
173/* Alternative perfctr range with full access. */
174#define MSR_IA32_PMC0 0x000004c1
175
173/* AMD64 MSRs. Not complete. See the architecture manual for a more 176/* AMD64 MSRs. Not complete. See the architecture manual for a more
174 complete list. */ 177 complete list. */
175 178
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 108dc75124d9..4809f075d977 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -310,6 +310,11 @@ union perf_capabilities {
310 u64 pebs_arch_reg:1; 310 u64 pebs_arch_reg:1;
311 u64 pebs_format:4; 311 u64 pebs_format:4;
312 u64 smm_freeze:1; 312 u64 smm_freeze:1;
313 /*
314 * PMU supports separate counter range for writing
315 * values > 32bit.
316 */
317 u64 full_width_write:1;
313 }; 318 };
314 u64 capabilities; 319 u64 capabilities;
315}; 320};
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index a6eccf1da42f..5877f372b03d 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2340,5 +2340,12 @@ __init int intel_pmu_init(void)
2340 } 2340 }
2341 } 2341 }
2342 2342
2343 /* Support full width counters using alternative MSR range */
2344 if (x86_pmu.intel_cap.full_width_write) {
2345 x86_pmu.max_period = x86_pmu.cntval_mask;
2346 x86_pmu.perfctr = MSR_IA32_PMC0;
2347 pr_cont("full-width counters, ");
2348 }
2349
2343 return 0; 2350 return 0;
2344} 2351}