diff options
-rw-r--r-- | kernel/events/core.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 142dbabc1615..f773fa13d7c2 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -947,7 +947,8 @@ static void put_ctx(struct perf_event_context *ctx) | |||
947 | * perf_event::mmap_mutex | 947 | * perf_event::mmap_mutex |
948 | * mmap_sem | 948 | * mmap_sem |
949 | */ | 949 | */ |
950 | static struct perf_event_context *perf_event_ctx_lock(struct perf_event *event) | 950 | static struct perf_event_context * |
951 | perf_event_ctx_lock_nested(struct perf_event *event, int nesting) | ||
951 | { | 952 | { |
952 | struct perf_event_context *ctx; | 953 | struct perf_event_context *ctx; |
953 | 954 | ||
@@ -960,7 +961,7 @@ again: | |||
960 | } | 961 | } |
961 | rcu_read_unlock(); | 962 | rcu_read_unlock(); |
962 | 963 | ||
963 | mutex_lock(&ctx->mutex); | 964 | mutex_lock_nested(&ctx->mutex, nesting); |
964 | if (event->ctx != ctx) { | 965 | if (event->ctx != ctx) { |
965 | mutex_unlock(&ctx->mutex); | 966 | mutex_unlock(&ctx->mutex); |
966 | put_ctx(ctx); | 967 | put_ctx(ctx); |
@@ -970,6 +971,12 @@ again: | |||
970 | return ctx; | 971 | return ctx; |
971 | } | 972 | } |
972 | 973 | ||
974 | static inline struct perf_event_context * | ||
975 | perf_event_ctx_lock(struct perf_event *event) | ||
976 | { | ||
977 | return perf_event_ctx_lock_nested(event, 0); | ||
978 | } | ||
979 | |||
973 | static void perf_event_ctx_unlock(struct perf_event *event, | 980 | static void perf_event_ctx_unlock(struct perf_event *event, |
974 | struct perf_event_context *ctx) | 981 | struct perf_event_context *ctx) |
975 | { | 982 | { |
@@ -3572,7 +3579,7 @@ static void perf_remove_from_owner(struct perf_event *event) | |||
3572 | */ | 3579 | */ |
3573 | static void put_event(struct perf_event *event) | 3580 | static void put_event(struct perf_event *event) |
3574 | { | 3581 | { |
3575 | struct perf_event_context *ctx = event->ctx; | 3582 | struct perf_event_context *ctx; |
3576 | 3583 | ||
3577 | if (!atomic_long_dec_and_test(&event->refcount)) | 3584 | if (!atomic_long_dec_and_test(&event->refcount)) |
3578 | return; | 3585 | return; |
@@ -3580,7 +3587,6 @@ static void put_event(struct perf_event *event) | |||
3580 | if (!is_kernel_event(event)) | 3587 | if (!is_kernel_event(event)) |
3581 | perf_remove_from_owner(event); | 3588 | perf_remove_from_owner(event); |
3582 | 3589 | ||
3583 | WARN_ON_ONCE(ctx->parent_ctx); | ||
3584 | /* | 3590 | /* |
3585 | * There are two ways this annotation is useful: | 3591 | * There are two ways this annotation is useful: |
3586 | * | 3592 | * |
@@ -3593,7 +3599,8 @@ static void put_event(struct perf_event *event) | |||
3593 | * the last filedesc died, so there is no possibility | 3599 | * the last filedesc died, so there is no possibility |
3594 | * to trigger the AB-BA case. | 3600 | * to trigger the AB-BA case. |
3595 | */ | 3601 | */ |
3596 | mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING); | 3602 | ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING); |
3603 | WARN_ON_ONCE(ctx->parent_ctx); | ||
3597 | perf_remove_from_context(event, true); | 3604 | perf_remove_from_context(event, true); |
3598 | mutex_unlock(&ctx->mutex); | 3605 | mutex_unlock(&ctx->mutex); |
3599 | 3606 | ||