In crash context, NMI should be suppressed before jump to a new kernel.
Naturally as the source of NMI on some arches, PMU should be turned off at
that time.

Introduce perf_pmu_disable_all() to achieve the goal.

Signed-off-by: Pingfan Liu <kernelf...@gmail.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Mark Rutland <mark.rutl...@arm.com>
Cc: Alexander Shishkin <alexander.shish...@linux.intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Borislav Petkov <b...@alien8.de>
Cc: "H. Peter Anvin" <h...@zytor.com>
Cc: Omar Sandoval <osan...@fb.com>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Mike Rapoport <r...@kernel.org>
Cc: x...@kernel.org
To: linux-kernel@vger.kernel.org
---
 include/linux/perf_event.h |  1 +
 kernel/events/core.c       | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 96450f6..f4baa87 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -965,6 +965,7 @@ extern const struct perf_event_attr 
*perf_event_attrs(struct perf_event *event);
 extern void perf_event_print_debug(void);
 extern void perf_pmu_disable(struct pmu *pmu);
 extern void perf_pmu_enable(struct pmu *pmu);
+extern void perf_pmu_disable_all(void);
 extern void perf_sched_cb_dec(struct pmu *pmu);
 extern void perf_sched_cb_inc(struct pmu *pmu);
 extern int perf_event_task_disable(void);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index dc568ca..c8e04a5 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1205,6 +1205,16 @@ void perf_pmu_enable(struct pmu *pmu)
                pmu->pmu_enable(pmu);
 }
 
+/* When crashed, other cpus hang in idle loop, so here do an emergency job 
under no lock */
+void perf_pmu_disable_all(void)
+{
+       struct pmu *pmu;
+
+       list_for_each_entry(pmu, &pmus, entry)
+               if (pmu->pmu_disable)
+                       pmu->pmu_disable(pmu);
+}
+
 static DEFINE_PER_CPU(struct list_head, active_ctx_list);
 
 /*
-- 
2.7.5

Reply via email to