aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/events/core.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1d1f030e2f1e..ef5e7cc686e3 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1950,7 +1950,16 @@ static int __perf_event_enable(void *info)
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
int err;
- if (WARN_ON_ONCE(!ctx->is_active))
+ /*
+ * There's a time window between 'ctx->is_active' check
+ * in perf_event_enable function and this place having:
+ * - IRQs on
+ * - ctx->lock unlocked
+ *
+ * where the task could be killed and 'ctx' deactivated
+ * by perf_event_exit_task.
+ */
+ if (!ctx->is_active)
return -EINVAL;
raw_spin_lock(&ctx->lock);