]> www.infradead.org Git - users/jedix/linux-maple.git/commit
x86: perf: prevent spurious PMU NMIs on Haswell systems
authorDan Duval <dan.duval@oracle.com>
Fri, 24 Oct 2014 19:14:14 +0000 (15:14 -0400)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Mon, 29 Jun 2015 15:36:56 +0000 (08:36 -0700)
commit2943624911e4f99e2f325c6e614dd1f46bfa2d3c
treeb0ed811bb08f658cb734e56491bb4c2327377cf1
parent095e7fe434a247feba4847dabb54559e040e4e08
x86: perf: prevent spurious PMU NMIs on Haswell systems

Orabug: 20996846

When "perf" is run on Haswell-based systems under UEK3, we've
noticed that "extra" NMIs are being generated by the Performance
Monitoring Unit (PMU).

The PMU contains counters that can count occurrences of certain
kinds of events, such as branch misses or instructions retired.
These counters can be programmed to issue an interrupt when they
reach certain pre-set values. linux uses vector 2, the NMI vector,
for these interrupts, so the PMU interrupts behave just like other
sources of NMIs such as watchdog timers. Each consumer of NMIs
within the kernel is responsible for identifying the interrupts
it's interested in.

In the current case, the linux PMU-support code is failing to
"claim" certain of the NMIs that are originating in the PMU.
What happens when no piece of kernel code claims an NMI is that
an ugly kernel message gets generated and, if the sysctl variable
"unknown_nmi_panic" is set nonzero (as it is by default on Exadata
systems), the system panics.

The current UEK3 PMU handler attempts to determine whether a given
NMI belongs to it by scanning the PMU hardware's potential NMI
sources to find out whether any of them has triggered. Apparently,
Haswell has potential NMI sources that are indeed getting triggered,
but of which the PMU handler is not aware.

This commit contains two measures designed to prevent these
extra NMIs.

First, we've moved the write to the local APIC's APIC_LVTPC register
from near the beginning of the PMU NMI handler to near the end.
Upstream has discovered empirically that this helps elminate
the spurious NMIs.  See:

    http://lists.openwall.net/linux-kernel/2013/06/19/712

for the original commit.

Second, this change takes advantage of a bit in the APIC_LVTPC
register that gets set when (and only when) a PMU-originated NMI
is being delivered to the CPU core.  This bit is a "mask" bit,
which when set, disables delivery of these NMIs to the core.
Having processed an NMI, system software must clear this bit in
order to enable delivery of the next one.

The fix involves sampling this bit and claiming the NMI if it's a
PMU NMI, even if its origin has not been otherwise determined.

Note that this change also helps render the PMU NMI handler immune
to the addition of more sources to the PMUs on future CPUs.

Signed-off-by: Dan Duval <dan.duval@oracle.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Guangyu Sun <guangyu.sun@oracle.com>
Signed-off-by: Dan Duval <dan.duval@oracle.com>
(cherry picked from commit ed921c01bcd2cad94dbd659ad2031a877e85acb8)

Conflict:

arch/x86/kernel/cpu/perf_event_intel.c

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
arch/x86/kernel/cpu/perf_event_intel.c