Re: [PATCH 1/7] perf: propagate perf_install_in_context errors up

From: Jiri Olsa
Date: Fri Jul 05 2019 - 10:13:19 EST


On Mon, Jul 01, 2019 at 11:59:49PM -0700, Ian Rogers wrote:
> The current __perf_install_in_context can fail and the error is ignored.
> Changing __perf_install_in_context can add new failure modes that need
> errors propagating up. This change prepares for this.
>
> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
> ---
> kernel/events/core.c | 38 +++++++++++++++++++++++++-------------
> 1 file changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 785d708f8553..4faa90f5a934 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -2558,11 +2558,12 @@ static int __perf_install_in_context(void *info)
> *
> * Very similar to event_function_call, see comment there.
> */
> -static void
> +static int
> perf_install_in_context(struct perf_event_context *ctx,
> struct perf_event *event,
> int cpu)
> {
> + int err;
> struct task_struct *task = READ_ONCE(ctx->task);
>
> lockdep_assert_held(&ctx->mutex);
> @@ -2577,15 +2578,15 @@ perf_install_in_context(struct perf_event_context *ctx,
> smp_store_release(&event->ctx, ctx);
>
> if (!task) {
> - cpu_function_call(cpu, __perf_install_in_context, event);
> - return;
> + err = cpu_function_call(cpu, __perf_install_in_context, event);
> + return err;
> }
>
> /*
> * Should not happen, we validate the ctx is still alive before calling.
> */
> if (WARN_ON_ONCE(task == TASK_TOMBSTONE))
> - return;
> + return 0;
>
> /*
> * Installing events is tricky because we cannot rely on ctx->is_active
> @@ -2619,8 +2620,9 @@ perf_install_in_context(struct perf_event_context *ctx,
> */
> smp_mb();
> again:
> - if (!task_function_call(task, __perf_install_in_context, event))
> - return;
> + err = task_function_call(task, __perf_install_in_context, event);
> + if (err)
> + return err;

you need to return in here if task_function_call succeeds and
continue in case of error, not the other way round, otherwise
bad things will happen ;-)

jirka

>
> raw_spin_lock_irq(&ctx->lock);
> task = ctx->task;
> @@ -2631,7 +2633,7 @@ perf_install_in_context(struct perf_event_context *ctx,
> * against perf_event_exit_task_context().
> */
> raw_spin_unlock_irq(&ctx->lock);
> - return;
> + return 0;
> }
> /*
> * If the task is not running, ctx->lock will avoid it becoming so,
> @@ -2643,6 +2645,7 @@ perf_install_in_context(struct perf_event_context *ctx,
> }
> add_event_to_ctx(event, ctx);
> raw_spin_unlock_irq(&ctx->lock);
> + return 0;
> }
>
> /*

SNIP