|
@@ -1950,7 +1950,16 @@ static int __perf_event_enable(void *info)
|
|
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
|
|
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
|
|
int err;
|
|
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;
|
|
return -EINVAL;
|
|
|
|
|
|
raw_spin_lock(&ctx->lock);
|
|
raw_spin_lock(&ctx->lock);
|