[PATCH 4/4] utrace_release_task: check REAP before utrace_reap()

Oleg Nesterov oleg at redhat.com
Mon Sep 7 22:06:45 UTC 2009


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);




More information about the utrace-devel mailing list