perf, x86: Add Nehelem PMU programming errata workaround

Implement the workaround for Intel Errata AAK100 and AAP53.

Also, remove the Core-i7 name for Nehalem events since there are
also Westmere based i7 chips.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
LKML-Reference: <1269608924.12097.147.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Peter Zijlstra
2010-03-26 14:08:44 +01:00
committed by Ingo Molnar
parent ea8e61b7bb
commit 11164cd4f6
4 changed files with 45 additions and 10 deletions

View File

@ -483,7 +483,7 @@ static void intel_pmu_disable_all(void)
intel_pmu_lbr_disable_all();
}
static void intel_pmu_enable_all(void)
static void intel_pmu_enable_all(int added)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@ -502,6 +502,40 @@ static void intel_pmu_enable_all(void)
}
}
/*
* Workaround for:
* Intel Errata AAK100 (model 26)
* Intel Errata AAP53 (model 30)
*
* These chips need to be 'reset' when adding counters by programming
* the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5
* either in sequence on the same PMC or on different PMCs.
*/
static void intel_pmu_nhm_enable_all(int added)
{
if (added) {
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int i;
wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2);
wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1);
wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5);
wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
for (i = 0; i < 3; i++) {
struct perf_event *event = cpuc->events[i];
if (!event)
continue;
__x86_pmu_enable_event(&event->hw);
}
}
intel_pmu_enable_all(added);
}
static inline u64 intel_pmu_get_status(void)
{
u64 status;
@ -658,7 +692,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
intel_pmu_drain_bts_buffer();
status = intel_pmu_get_status();
if (!status) {
intel_pmu_enable_all();
intel_pmu_enable_all(0);
return 0;
}
@ -707,7 +741,7 @@ again:
goto again;
done:
intel_pmu_enable_all();
intel_pmu_enable_all(0);
return 1;
}
@ -920,7 +954,8 @@ static __init int intel_pmu_init(void)
intel_pmu_lbr_init_nhm();
x86_pmu.event_constraints = intel_nehalem_event_constraints;
pr_cont("Nehalem/Corei7 events, ");
x86_pmu.enable_all = intel_pmu_nhm_enable_all;
pr_cont("Nehalem events, ");
break;
case 28: /* Atom */