aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2018-09-25 11:58:35 -0400
committerIngo Molnar <mingo@kernel.org>2018-10-02 03:37:56 -0400
commita9f9772114c8b07ae75bcb3654bd017461248095 (patch)
treeaf2008edb00495276c182e7d77f8c334ab502ef1
parent291d0e5d81e101392379217b06251fe8c27f1f80 (diff)
perf/core: Fix perf_pmu_unregister() locking
When we unregister a PMU, we fail to serialize the @pmu_idr properly. Fix that by doing the entire thing under pmu_lock. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: 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 <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Fixes: 2e80a82a49c4 ("perf: Dynamic pmu types") Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/events/core.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index dcb093e7b377..dfb1d951789e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -9431,9 +9431,7 @@ static void free_pmu_context(struct pmu *pmu)
9431 if (pmu->task_ctx_nr > perf_invalid_context) 9431 if (pmu->task_ctx_nr > perf_invalid_context)
9432 return; 9432 return;
9433 9433
9434 mutex_lock(&pmus_lock);
9435 free_percpu(pmu->pmu_cpu_context); 9434 free_percpu(pmu->pmu_cpu_context);
9436 mutex_unlock(&pmus_lock);
9437} 9435}
9438 9436
9439/* 9437/*
@@ -9689,12 +9687,8 @@ EXPORT_SYMBOL_GPL(perf_pmu_register);
9689 9687
9690void perf_pmu_unregister(struct pmu *pmu) 9688void perf_pmu_unregister(struct pmu *pmu)
9691{ 9689{
9692 int remove_device;
9693
9694 mutex_lock(&pmus_lock); 9690 mutex_lock(&pmus_lock);
9695 remove_device = pmu_bus_running;
9696 list_del_rcu(&pmu->entry); 9691 list_del_rcu(&pmu->entry);
9697 mutex_unlock(&pmus_lock);
9698 9692
9699 /* 9693 /*
9700 * We dereference the pmu list under both SRCU and regular RCU, so 9694 * We dereference the pmu list under both SRCU and regular RCU, so
@@ -9706,13 +9700,14 @@ void perf_pmu_unregister(struct pmu *pmu)
9706 free_percpu(pmu->pmu_disable_count); 9700 free_percpu(pmu->pmu_disable_count);
9707 if (pmu->type >= PERF_TYPE_MAX) 9701 if (pmu->type >= PERF_TYPE_MAX)
9708 idr_remove(&pmu_idr, pmu->type); 9702 idr_remove(&pmu_idr, pmu->type);
9709 if (remove_device) { 9703 if (pmu_bus_running) {
9710 if (pmu->nr_addr_filters) 9704 if (pmu->nr_addr_filters)
9711 device_remove_file(pmu->dev, &dev_attr_nr_addr_filters); 9705 device_remove_file(pmu->dev, &dev_attr_nr_addr_filters);
9712 device_del(pmu->dev); 9706 device_del(pmu->dev);
9713 put_device(pmu->dev); 9707 put_device(pmu->dev);
9714 } 9708 }
9715 free_pmu_context(pmu); 9709 free_pmu_context(pmu);
9710 mutex_unlock(&pmus_lock);
9716} 9711}
9717EXPORT_SYMBOL_GPL(perf_pmu_unregister); 9712EXPORT_SYMBOL_GPL(perf_pmu_unregister);
9718 9713