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 <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Omar Sandoval <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: [email protected] To: [email protected] --- 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

