Re: Q: perf_install_in_context/perf_event_enable are racy?

From: Oleg Nesterov
Date: Fri Jan 28 2011 - 11:37:04 EST


On 01/28, Peter Zijlstra wrote:
>
> On Fri, 2011-01-28 at 12:52 +0100, Peter Zijlstra wrote:
> > Right, so in case the perf_event_task_sched_in() missed the assignment
> > of ->perf_event_ctxp[n], then our above story falls flat on its face.
> >
> > Because then we can not rely on ->in_active being set for running tasks.
> >
> > So we need a task_curr() test under that lock, which would need
> > perf_event_task_sched_out() to be done _before_ we set rq->curr = next,
> > I _think_.
>
> Ok, so how about something like this:
>
> if task_oncpu_function_call() managed to execute the function proper,
> we're done. Otherwise, if while holding the lock, task_curr() is true,
> it means the task is now current and we should try again, if its not, it
> cannot become current because us holding ctx->lock blocks
> perf_event_task_sched_in().
>
> Hmm?

I _feel_ this patch should be right. To me, this even makes the code
more understandable. But I'll try to re-read it once again, somehow
I can't concentrace today.

> @@ -1031,25 +1032,29 @@ perf_install_in_context(struct perf_event_context *ctx,
> }
>
> retry:
> - task_oncpu_function_call(task, __perf_install_in_context,
> - event);
> + ret = task_oncpu_function_call(task,
> + __perf_install_in_context, event);
> +
> + if (!ret)
> + return;
>
> raw_spin_lock_irq(&ctx->lock);
> +
> /*
> - * we need to retry the smp call.
> + * If the task_oncpu_function_call() failed, re-check task_curr() now
> + * that we hold ctx->lock(), if it is running retry the IPI.
> */
> - if (ctx->is_active && list_empty(&event->group_entry)) {
> + if (task_curr(task)) {

Yes, but task_curr() should be exported.

One note. If this patch is correct (I think it is), then this check
in __perf_install_in_context() and __perf_event_enable()

if (cpuctx->task_ctx || ctx->task != current)
return;

should become unneeded. It should be removed or turned into WARN_ON()
imho, otherwise it looks confusing.

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/