perf, x86, nmi: Move LVT un-masking into irq handlers

It was noticed that P4 machines were generating double NMIs for
each perf event. These extra NMIs lead to 'Dazed and confused'
messages on the screen.

I tracked this down to a P4 quirk that said the overflow bit had
to be cleared before re-enabling the apic LVT mask. My first
attempt was to move the un-masking inside the perf nmi handler
from before the chipset NMI handler to after.

This broke Nehalem boxes that seem to like the unmasking before
the counters themselves are re-enabled.

In order to keep this change simple for 2.6.39, I decided to
just simply move the apic LVT un-masking to the beginning of all
the chipset NMI handlers, with the exception of Pentium4's to
fix the double NMI issue.

Later on we can move the un-masking to later in the handlers to
save a number of 'extra' NMIs on those particular chipsets.

I tested this change on a P4 machine, an AMD machine, a Nehalem
box, and a core2quad box. 'perf top' worked correctly along
with various other small 'perf record' runs. Anything high
stress breaks all the machines but that is a different problem.

Thanks to various people for testing different versions of this
patch.

Reported-and-tested-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Don Zickus <dzickus@redhat.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Link: http://lkml.kernel.org/r/1303900353-10242-1-git-send-email-dzickus@redhat.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
CC: Cyrill Gorcunov <gorcunov@gmail.com>

authored by Don Zickus and committed by Ingo Molnar 2bce5dac 6c8a7213

+33 -6
+10 -2
arch/x86/kernel/cpu/perf_event.c
··· 1288 1288 1289 1289 cpuc = &__get_cpu_var(cpu_hw_events); 1290 1290 1291 + /* 1292 + * Some chipsets need to unmask the LVTPC in a particular spot 1293 + * inside the nmi handler. As a result, the unmasking was pushed 1294 + * into all the nmi handlers. 1295 + * 1296 + * This generic handler doesn't seem to have any issues where the 1297 + * unmasking occurs so it was left at the top. 1298 + */ 1299 + apic_write(APIC_LVTPC, APIC_DM_NMI); 1300 + 1291 1301 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 1292 1302 if (!test_bit(idx, cpuc->active_mask)) { 1293 1303 /* ··· 1383 1373 default: 1384 1374 return NOTIFY_DONE; 1385 1375 } 1386 - 1387 - apic_write(APIC_LVTPC, APIC_DM_NMI); 1388 1376 1389 1377 handled = x86_pmu.handle_irq(args->regs); 1390 1378 if (!handled)
+10
arch/x86/kernel/cpu/perf_event_intel.c
··· 933 933 934 934 cpuc = &__get_cpu_var(cpu_hw_events); 935 935 936 + /* 937 + * Some chipsets need to unmask the LVTPC in a particular spot 938 + * inside the nmi handler. As a result, the unmasking was pushed 939 + * into all the nmi handlers. 940 + * 941 + * This handler doesn't seem to have any issues with the unmasking 942 + * so it was left at the top. 943 + */ 944 + apic_write(APIC_LVTPC, APIC_DM_NMI); 945 + 936 946 intel_pmu_disable_all(); 937 947 handled = intel_pmu_drain_bts_buffer(); 938 948 status = intel_pmu_get_status();
+13 -4
arch/x86/kernel/cpu/perf_event_p4.c
··· 950 950 x86_pmu_stop(event, 0); 951 951 } 952 952 953 - if (handled) { 954 - /* p4 quirk: unmask it again */ 955 - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 953 + if (handled) 956 954 inc_irq_stat(apic_perf_irqs); 957 - } 955 + 956 + /* 957 + * When dealing with the unmasking of the LVTPC on P4 perf hw, it has 958 + * been observed that the OVF bit flag has to be cleared first _before_ 959 + * the LVTPC can be unmasked. 960 + * 961 + * The reason is the NMI line will continue to be asserted while the OVF 962 + * bit is set. This causes a second NMI to generate if the LVTPC is 963 + * unmasked before the OVF bit is cleared, leading to unknown NMI 964 + * messages. 965 + */ 966 + apic_write(APIC_LVTPC, APIC_DM_NMI); 958 967 959 968 return handled; 960 969 }