diff options
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index a9047463fd83..c97e82518403 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -308,8 +308,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
308 | static void | 308 | static void |
309 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) | 309 | list_del_event(struct perf_event *event, struct perf_event_context *ctx) |
310 | { | 310 | { |
311 | struct perf_event *sibling, *tmp; | ||
312 | |||
313 | if (list_empty(&event->group_entry)) | 311 | if (list_empty(&event->group_entry)) |
314 | return; | 312 | return; |
315 | ctx->nr_events--; | 313 | ctx->nr_events--; |
@@ -333,6 +331,12 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx) | |||
333 | */ | 331 | */ |
334 | if (event->state > PERF_EVENT_STATE_OFF) | 332 | if (event->state > PERF_EVENT_STATE_OFF) |
335 | event->state = PERF_EVENT_STATE_OFF; | 333 | event->state = PERF_EVENT_STATE_OFF; |
334 | } | ||
335 | |||
336 | static void | ||
337 | perf_destroy_group(struct perf_event *event, struct perf_event_context *ctx) | ||
338 | { | ||
339 | struct perf_event *sibling, *tmp; | ||
336 | 340 | ||
337 | /* | 341 | /* |
338 | * If this was a group event with sibling events then | 342 | * If this was a group event with sibling events then |
@@ -1868,6 +1872,12 @@ int perf_event_release_kernel(struct perf_event *event) | |||
1868 | { | 1872 | { |
1869 | struct perf_event_context *ctx = event->ctx; | 1873 | struct perf_event_context *ctx = event->ctx; |
1870 | 1874 | ||
1875 | /* | ||
1876 | * Remove from the PMU, can't get re-enabled since we got | ||
1877 | * here because the last ref went. | ||
1878 | */ | ||
1879 | perf_event_disable(event); | ||
1880 | |||
1871 | WARN_ON_ONCE(ctx->parent_ctx); | 1881 | WARN_ON_ONCE(ctx->parent_ctx); |
1872 | /* | 1882 | /* |
1873 | * There are two ways this annotation is useful: | 1883 | * There are two ways this annotation is useful: |
@@ -1882,7 +1892,10 @@ int perf_event_release_kernel(struct perf_event *event) | |||
1882 | * to trigger the AB-BA case. | 1892 | * to trigger the AB-BA case. |
1883 | */ | 1893 | */ |
1884 | mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); | 1894 | mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); |
1885 | perf_event_remove_from_context(event); | 1895 | raw_spin_lock_irq(&ctx->lock); |
1896 | list_del_event(event, ctx); | ||
1897 | perf_destroy_group(event, ctx); | ||
1898 | raw_spin_unlock_irq(&ctx->lock); | ||
1886 | mutex_unlock(&ctx->mutex); | 1899 | mutex_unlock(&ctx->mutex); |
1887 | 1900 | ||
1888 | mutex_lock(&event->owner->perf_event_mutex); | 1901 | mutex_lock(&event->owner->perf_event_mutex); |