| From 1bfd492dff8549b89daca4258dc616a0575b10c0 Mon Sep 17 00:00:00 2001 |
| From: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Date: Tue, 10 Dec 2019 12:51:01 +0200 |
| Subject: [PATCH] perf/x86/intel: Fix PT PMI handling |
| |
| commit 92ca7da4bdc24d63bb0bcd241c11441ddb63b80a upstream. |
| |
| Commit: |
| |
| ccbebba4c6bf ("perf/x86/intel/pt: Bypass PT vs. LBR exclusivity if the core supports it") |
| |
| skips the PT/LBR exclusivity check on CPUs where PT and LBRs coexist, but |
| also inadvertently skips the active_events bump for PT in that case, which |
| is a bug. If there aren't any hardware events at the same time as PT, the |
| PMI handler will ignore PT PMIs, as active_events reads zero in that case, |
| resulting in the "Uhhuh" spurious NMI warning and PT data loss. |
| |
| Fix this by always increasing active_events for PT events. |
| |
| Fixes: ccbebba4c6bf ("perf/x86/intel/pt: Bypass PT vs. LBR exclusivity if the core supports it") |
| Reported-by: Vitaly Slobodskoy <vitaly.slobodskoy@intel.com> |
| Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Acked-by: Alexey Budankov <alexey.budankov@linux.intel.com> |
| Cc: Jiri Olsa <jolsa@kernel.org> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Link: https://lkml.kernel.org/r/20191210105101.77210-1-alexander.shishkin@linux.intel.com |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c |
| index 3cd94a21bd53..bfcb077503e6 100644 |
| --- a/arch/x86/events/core.c |
| +++ b/arch/x86/events/core.c |
| @@ -375,7 +375,7 @@ int x86_add_exclusive(unsigned int what) |
| * LBR and BTS are still mutually exclusive. |
| */ |
| if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt) |
| - return 0; |
| + goto out; |
| |
| if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) { |
| mutex_lock(&pmc_reserve_mutex); |
| @@ -387,6 +387,7 @@ int x86_add_exclusive(unsigned int what) |
| mutex_unlock(&pmc_reserve_mutex); |
| } |
| |
| +out: |
| atomic_inc(&active_events); |
| return 0; |
| |
| @@ -397,11 +398,15 @@ int x86_add_exclusive(unsigned int what) |
| |
| void x86_del_exclusive(unsigned int what) |
| { |
| + atomic_dec(&active_events); |
| + |
| + /* |
| + * See the comment in x86_add_exclusive(). |
| + */ |
| if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt) |
| return; |
| |
| atomic_dec(&x86_pmu.lbr_exclusive[what]); |
| - atomic_dec(&active_events); |
| } |
| |
| int x86_setup_perfctr(struct perf_event *event) |
| -- |
| 2.7.4 |
| |