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 <[email protected]>
> ---
>  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

Reply via email to