aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/events/core.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f773fa13d7c2..37cc20e8aa3b 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7027,6 +7027,20 @@ void perf_pmu_unregister(struct pmu *pmu)
7027} 7027}
7028EXPORT_SYMBOL_GPL(perf_pmu_unregister); 7028EXPORT_SYMBOL_GPL(perf_pmu_unregister);
7029 7029
7030static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
7031{
7032 int ret;
7033
7034 if (!try_module_get(pmu->module))
7035 return -ENODEV;
7036 event->pmu = pmu;
7037 ret = pmu->event_init(event);
7038 if (ret)
7039 module_put(pmu->module);
7040
7041 return ret;
7042}
7043
7030struct pmu *perf_init_event(struct perf_event *event) 7044struct pmu *perf_init_event(struct perf_event *event)
7031{ 7045{
7032 struct pmu *pmu = NULL; 7046 struct pmu *pmu = NULL;
@@ -7039,24 +7053,14 @@ struct pmu *perf_init_event(struct perf_event *event)
7039 pmu = idr_find(&pmu_idr, event->attr.type); 7053 pmu = idr_find(&pmu_idr, event->attr.type);
7040 rcu_read_unlock(); 7054 rcu_read_unlock();
7041 if (pmu) { 7055 if (pmu) {
7042 if (!try_module_get(pmu->module)) { 7056 ret = perf_try_init_event(pmu, event);
7043 pmu = ERR_PTR(-ENODEV);
7044 goto unlock;
7045 }
7046 event->pmu = pmu;
7047 ret = pmu->event_init(event);
7048 if (ret) 7057 if (ret)
7049 pmu = ERR_PTR(ret); 7058 pmu = ERR_PTR(ret);
7050 goto unlock; 7059 goto unlock;
7051 } 7060 }
7052 7061
7053 list_for_each_entry_rcu(pmu, &pmus, entry) { 7062 list_for_each_entry_rcu(pmu, &pmus, entry) {
7054 if (!try_module_get(pmu->module)) { 7063 ret = perf_try_init_event(pmu, event);
7055 pmu = ERR_PTR(-ENODEV);
7056 goto unlock;
7057 }
7058 event->pmu = pmu;
7059 ret = pmu->event_init(event);
7060 if (!ret) 7064 if (!ret)
7061 goto unlock; 7065 goto unlock;
7062 7066