perf/x86/intel: Support full width counting
authorAndi Kleen <ak@linux.intel.com>
Tue, 25 Jun 2013 15:12:33 +0000 (08:12 -0700)
committerIngo Molnar <mingo@kernel.org>
Wed, 26 Jun 2013 09:59:25 +0000 (11:59 +0200)
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>
arch/x86/include/uapi/asm/msr-index.h
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_intel.c

index 2af848dfa75424b7798924dd9a91524af7f088e3..bb0465090ae53eb3246b5022d187dd4517bd39d0 100644 (file)
 #define MSR_KNC_EVNTSEL0               0x00000028
 #define MSR_KNC_EVNTSEL1               0x00000029
 
+/* Alternative perfctr range with full access. */
+#define MSR_IA32_PMC0                  0x000004c1
+
 /* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
 
index 108dc75124d92fab081345fd3a9c80ba5401c152..4809f075d977df046662506bc37704916cc59c17 100644 (file)
@@ -310,6 +310,11 @@ union perf_capabilities {
                u64     pebs_arch_reg:1;
                u64     pebs_format:4;
                u64     smm_freeze:1;
+               /*
+                * PMU supports separate counter range for writing
+                * values > 32bit.
+                */
+               u64     full_width_write:1;
        };
        u64     capabilities;
 };
index a6eccf1da42f178fbeda43a9a5f456bca721cc8d..5877f372b03d8253c7252c51637fb0c3149be615 100644 (file)
@@ -2340,5 +2340,12 @@ __init int intel_pmu_init(void)
                }
        }
 
+       /* Support full width counters using alternative MSR range */
+       if (x86_pmu.intel_cap.full_width_write) {
+               x86_pmu.max_period = x86_pmu.cntval_mask;
+               x86_pmu.perfctr = MSR_IA32_PMC0;
+               pr_cont("full-width counters, ");
+       }
+
        return 0;
 }