perf events, x86: Work around the Nehalem AAJ80 erratum
Subsystems (2)
Commit-ID: ec75a71634dabe439db91c1ef51d5099f4493808 Gitweb: http://git.kernel.org/tip/ec75a71634dabe439db91c1ef51d5099f4493808 Author: Ingo Molnar <[email protected]> AuthorDate: Wed, 27 Apr 2011 11:51:41 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 26 Apr 2011 19:34:34 +0200
perf events, x86: Work around the Nehalem AAJ80 erratum
On Nehalem CPUs the retired branch-misses event can be completely bogus, when there are no branch-misses occuring. When there are a lot of branch misses then the count is pretty accurate. Still, this leaves us with an event that over-counts a lot.
Detect this erratum and work it around by using BR_MISP_EXEC.ANY events. These will also count speculated branches but still it's a lot more precise in practice than the architectural event.
Acked-by Peter Zijlstra <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Signed-off-by Ingo Molnar <[email protected]>
--- arch/x86/kernel/cpu/perf_event_intel.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/perf_event_intel.c +14 -2
@@ -25,7 +25,7 @@ struct intel_percore {/* * Intel PerfMon, used on Core and later. */ -static const u64 intel_perfmon_event_map[] = +static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX ]__read_mostly = { [PERF_COUNT_HW_CPU_CYCLES ] =0x003c , [PERF_COUNT_HW_INSTRUCTIONS ] =0x00c0 ,
@@ -1308,7 +1308,7 @@ static void intel_clovertown_quirks(void)* AJ106 could possibly be worked around by not allowing LBR * usage from PEBS, including the fixup. * AJ68 could possibly be worked around by always programming -* a pebs_event_reset[0] value and coping with the lost events. +* a pebs_event_reset[0] value and coping with the lost events. * * But taken together it might just make sense to not enable PEBS on * these chips.
@@ -1412,6 +1412,18 @@ static __init int intel_pmu_init(void) x86_pmu.percore_constraints = intel_nehalem_percore_constraints; x86_pmu.enable_all = intel_pmu_nhm_enable_all; x86_pmu.extra_regs = intel_nehalem_extra_regs; + +if (ebx &0x40 ) { +/* +* Erratum AAJ80 detected, we work it around by using +* the BR_MISP_EXEC.ANY event. This will over-count +* branch-misses, but it's still much better than the +* architectural event which is often completely bogus: +*/ + intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES ] =0x7f89 ; + +pr_cont ("erratum AAJ80 worked around, " ); + }pr_cont ("Nehalem events, " );break ;