diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/core.c | 28 |
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 | } |
| 7028 | EXPORT_SYMBOL_GPL(perf_pmu_unregister); | 7028 | EXPORT_SYMBOL_GPL(perf_pmu_unregister); |
| 7029 | 7029 | ||
| 7030 | static 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 | |||
| 7030 | struct pmu *perf_init_event(struct perf_event *event) | 7044 | struct 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 | ||
