| From d9f91eee7d30d247251ef07f647007778bd202d0 Mon Sep 17 00:00:00 2001 |
| From: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Date: Tue, 22 Oct 2019 10:39:40 +0300 |
| Subject: [PATCH] perf/aux: Fix AUX output stopping |
| |
| commit f3a519e4add93b7b31a6616f0b09635ff2e6a159 upstream. |
| |
| Commit: |
| |
| 8a58ddae2379 ("perf/core: Fix exclusive events' grouping") |
| |
| allows CAP_EXCLUSIVE events to be grouped with other events. Since all |
| of those also happen to be AUX events (which is not the case the other |
| way around, because arch/s390), this changes the rules for stopping the |
| output: the AUX event may not be on its PMU's context any more, if it's |
| grouped with a HW event, in which case it will be on that HW event's |
| context instead. If that's the case, munmap() of the AUX buffer can't |
| find and stop the AUX event, potentially leaving the last reference with |
| the atomic context, which will then end up freeing the AUX buffer. This |
| will then trip warnings: |
| |
| Fix this by using the context's PMU context when looking for events |
| to stop, instead of the event's PMU context. |
| |
| Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Cc: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Cc: Jiri Olsa <jolsa@redhat.com> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Stephane Eranian <eranian@google.com> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Vince Weaver <vincent.weaver@maine.edu> |
| Cc: stable@vger.kernel.org |
| Link: https://lkml.kernel.org/r/20191022073940.61814-1-alexander.shishkin@linux.intel.com |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/events/core.c b/kernel/events/core.c |
| index 4bc15cff1026..a690905247fe 100644 |
| --- a/kernel/events/core.c |
| +++ b/kernel/events/core.c |
| @@ -6837,7 +6837,7 @@ static void __perf_event_output_stop(struct perf_event *event, void *data) |
| static int __perf_pmu_output_stop(void *info) |
| { |
| struct perf_event *event = info; |
| - struct pmu *pmu = event->pmu; |
| + struct pmu *pmu = event->ctx->pmu; |
| struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); |
| struct remote_output ro = { |
| .rb = event->rb, |
| -- |
| 2.7.4 |
| |