aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2013-06-17 20:36:50 -0400
committerIngo Molnar <mingo@kernel.org>2013-06-19 08:43:34 -0400
commit72db55964695dcd4aa15950f3b2fb7c09ad79829 (patch)
tree907d805def5b801550974a00c8e63abfbc18dd14
parent3044318f1f3a2a0a636b4c751ddb7169cb1b11b2 (diff)
perf/x86/intel: Move NMI clearing to end of PMI handler
This avoids some problems with spurious PMIs on Haswell. Haswell seems to behave more like P4 in this regard. Do the same thing as the P4 perf handler by unmasking the NMI only at the end. Shouldn't make any difference for earlier family 6 cores. (Tested on Haswell, IvyBridge, Westmere, Saltwell (Atom).) Signed-off-by: Andi Kleen <ak@linux.intel.com> Cc: Andi Kleen <ak@linux.jf.intel.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Link: http://lkml.kernel.org/r/1371515812-9646-5-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/cpu/perf_event.h1
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c20
2 files changed, 13 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index fb7fe44e6b96..f43473c50f52 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -378,6 +378,7 @@ struct x86_pmu {
378 struct event_constraint *event_constraints; 378 struct event_constraint *event_constraints;
379 struct x86_pmu_quirk *quirks; 379 struct x86_pmu_quirk *quirks;
380 int perfctr_second_write; 380 int perfctr_second_write;
381 bool late_ack;
381 382
382 /* 383 /*
383 * sysfs attrs 384 * sysfs attrs
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 4a4c4ba0c1d7..877672c43347 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1185,15 +1185,11 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
1185 cpuc = &__get_cpu_var(cpu_hw_events); 1185 cpuc = &__get_cpu_var(cpu_hw_events);
1186 1186
1187 /* 1187 /*
1188 * Some chipsets need to unmask the LVTPC in a particular spot 1188 * No known reason to not always do late ACK,
1189 * inside the nmi handler. As a result, the unmasking was pushed 1189 * but just in case do it opt-in.
1190 * into all the nmi handlers.
1191 *
1192 * This handler doesn't seem to have any issues with the unmasking
1193 * so it was left at the top.
1194 */ 1190 */
1195 apic_write(APIC_LVTPC, APIC_DM_NMI); 1191 if (!x86_pmu.late_ack)
1196 1192 apic_write(APIC_LVTPC, APIC_DM_NMI);
1197 intel_pmu_disable_all(); 1193 intel_pmu_disable_all();
1198 handled = intel_pmu_drain_bts_buffer(); 1194 handled = intel_pmu_drain_bts_buffer();
1199 status = intel_pmu_get_status(); 1195 status = intel_pmu_get_status();
@@ -1257,6 +1253,13 @@ again:
1257 1253
1258done: 1254done:
1259 intel_pmu_enable_all(0); 1255 intel_pmu_enable_all(0);
1256 /*
1257 * Only unmask the NMI after the overflow counters
1258 * have been reset. This avoids spurious NMIs on
1259 * Haswell CPUs.
1260 */
1261 if (x86_pmu.late_ack)
1262 apic_write(APIC_LVTPC, APIC_DM_NMI);
1260 return handled; 1263 return handled;
1261} 1264}
1262 1265
@@ -2260,6 +2263,7 @@ __init int intel_pmu_init(void)
2260 case 70: 2263 case 70:
2261 case 71: 2264 case 71:
2262 case 63: 2265 case 63:
2266 x86_pmu.late_ack = true;
2263 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); 2267 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids));
2264 memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); 2268 memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
2265 2269