On 09/07, Roland McGrath wrote:
>
> In the original code, utrace_release_task() would not be called at all when
> there are no engines attached.  IMHO that is the optimization we want to
> get back to.
>
> It may still be too early in the morning for me to be thinking clearly.

and too late for me ;) will reply tomorrow.

Oleg.

> diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
> index e249770..0000000 100644  
> --- a/include/linux/tracehook.h
> +++ b/include/linux/tracehook.h
> @@ -362,7 +362,12 @@ static inline void tracehook_report_vfor
>   */
>  static inline void tracehook_prepare_release_task(struct task_struct *task)
>  {
> -     utrace_release_task(task);
> +     /*
> +      * See kernel/utrace.c:utrace_attach_task() about this barrier.
> +      */
> +     smp_mb();
> +     if (task_utrace_flags(task))
> +             utrace_release_task(task);
>  }
>  
>  /**
> diff --git a/kernel/utrace.c b/kernel/utrace.c
> index 76d0d84..0000000 100644  
> --- a/kernel/utrace.c
> +++ b/kernel/utrace.c
> @@ -143,13 +143,13 @@ static int utrace_add_engine(struct task
>  
>       spin_lock(&utrace->lock);
>  
> -     if (utrace->reap) {
> +     if (unlikely(utrace->reap)) {
>               /*
>                * Already entered utrace_release_task(), cannot attach now.
>                */
>               ret = -ESRCH;
>       } else if ((flags & UTRACE_ATTACH_EXCLUSIVE) &&
> -         unlikely(matching_engine(utrace, flags, ops, data))) {
> +                unlikely(matching_engine(utrace, flags, ops, data))) {
>               ret = -EEXIST;
>       } else {
>               /*
> @@ -216,16 +216,19 @@ struct utrace_engine *utrace_attach_task
>  
>       utrace = &target->utrace;
>  
> -     if (unlikely(target->exit_state == EXIT_DEAD)) {
> -             /*
> -              * The target has already been reaped.
> -              * Check this early, though it's not synchronized.
> -              * utrace_add_engine() will do the final check.
> -              */
> -             if (!(flags & UTRACE_ATTACH_CREATE))
> -                     return ERR_PTR(-ENOENT);
> -             return ERR_PTR(-ESRCH);
> -     }
> +     /*
> +      * If it already could be getting reaped, we cannot attach now.
> +      * The barrier ensures this check precedes utrace_add_engine()
> +      * setting ->utrace_flags.  tracehook_prepare_release_task() has
> +      * the corresponding barrier, after setting EXIT_DEAD and before
> +      * checking ->utrace_flags to decide to call utrace_release_task().
> +      */
> +     ret = target->exit_state;
> +     smp_mb();
> +
> +     if (unlikely(ret == EXIT_DEAD))
> +             return ERR_PTR((flags & UTRACE_ATTACH_CREATE) ?
> +                            -ESRCH : -ENOENT);
>  
>       if (!(flags & UTRACE_ATTACH_CREATE)) {
>               spin_lock(&utrace->lock);

Reply via email to