public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@tv-sign.ru>
To: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] do_wait reorganization
Date: Sat, 29 Mar 2008 13:35:13 +0300	[thread overview]
Message-ID: <20080329103513.GA359@tv-sign.ru> (raw)
In-Reply-To: <20080329033412.120EE26FA1D@magilla.localdomain>

On 03/28, Roland McGrath wrote:
>
> +static int wait_consider_task(struct task_struct *parent,
> +			      struct task_struct *p, int *retval,
> +			      enum pid_type type, struct pid *pid, int options,
> +			      struct siginfo __user *infop,
> +			      int __user *stat_addr, struct rusage __user *ru)
> +{
> +	int ret = eligible_child(type, pid, options, p);
> +	if (!ret)
> +		return 0;
> +
> +	if (unlikely(ret < 0)) {
> +		read_unlock(&tasklist_lock);
> +		*retval = ret;

Please note that eligible_child() drops tasklist_lock if it returns error
(ret < 0), so the "read_unlock" above is wrong.

> +static int do_wait_thread(struct task_struct *tsk, int *retval,
> +			  enum pid_type type, struct pid *pid, int options,
> +			  struct siginfo __user *infop, int __user *stat_addr,
> +			  struct rusage __user *ru)
> +{
> +	struct task_struct *p;
> +
> +	list_for_each_entry(p, &tsk->children, sibling) {
> +		if (wait_consider_task(tsk, p, retval, type, pid, options,
> +				       infop, stat_addr, ru))
> +			return 1;
> +	}
> +
> +	/*
> +	 * If we never saw an eligile child, check for children stolen by
> +	 * ptrace.  We don't leave -ECHILD in *@retval if there are any,
> +	 * because we will eventually be allowed to wait for them again.
> +	 */
> +	if (*retval)
> +		list_for_each_entry(p, &tsk->ptrace_children, ptrace_list) {
> +			int ret = eligible_child(type, pid, options, p);
> +			if (ret) {
> +				*retval = unlikely(ret < 0) ? ret : 0;

This is not right. If ret < 0, we set *retval = ret, but then return 0.
We should return 1, so that the caller (do_wait) will report the error.

Note again that eligible_child() has already dropped tasklist, so not
only we don't return the error, we continue to run without tasklist
held, this is bug.

>  static long do_wait(enum pid_type type, struct pid *pid, int options,
>  		    struct siginfo __user *infop, int __user *stat_addr,
>  		    struct rusage __user *ru)
>  {
>
> [...snip...]
>
> -	if (flag) {
> -		if (options & WNOHANG)
> -			goto end;
> +	if (!retval && !(options & WNOHANG)) {
>  		retval = -ERESTARTSYS;
> -		if (signal_pending(current))
> -			goto end;
> -		schedule();
> -		goto repeat;
> +		if (!signal_pending(current)) {
> +			schedule();
> +			goto repeat;
> +		}
>  	}
> -	retval = -ECHILD;
> +
>  end:
>  	current->state = TASK_RUNNING;
>  	remove_wait_queue(&current->signal->wait_chldexit,&wait);

If !retval and WNOHANG, we should return -ECHILD, but with this patch
we return 0.

Perhaps I missed something, but personally I don't like the usage of
"int *retval", imho this really complicates the code. I think it is better
to use the returned values directly, but pass "&flag" to do_wait_thread().
We only need the pointer to avoid the unnecessary scanning of ->ptrace_children.
Better yet, we can split do_wait_thread() into 2 functions, and do not pass
the pointer at all. But I didn't read the next patch yet (will do tomorrow),
perhaps I missed the point of this approach.

Oleg.


  parent reply	other threads:[~2008-03-29 10:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-29  3:34 [PATCH 1/2] do_wait reorganization Roland McGrath
2008-03-29  3:35 ` [PATCH 2/2] ptrace children revamp Roland McGrath
2008-03-29 10:39   ` Oleg Nesterov
2008-03-29 13:10     ` Oleg Nesterov
2008-03-29 14:37       ` Oleg Nesterov
2008-04-04 21:00       ` Roland McGrath
2008-04-05 14:06         ` Oleg Nesterov
2008-04-09 20:15           ` Roland McGrath
2008-04-13 14:24             ` Oleg Nesterov
2008-04-15  1:41               ` Roland McGrath
2008-03-29 10:35 ` Oleg Nesterov [this message]
2008-03-31  3:54   ` [PATCH 1/2] do_wait reorganization Roland McGrath
2008-03-29 16:16 ` Linus Torvalds
2008-03-31  3:27   ` Roland McGrath
2008-03-31  3:57   ` [PATCH 1/3] " Roland McGrath
2008-03-31  3:59     ` [PATCH 2/3] ptrace children revamp Roland McGrath
2008-03-31  9:12       ` Oleg Nesterov
2008-03-31  3:59     ` [PATCH 3/3] do_wait: return security_task_wait() error code in place of -ECHILD Roland McGrath
2008-03-31 11:03       ` Oleg Nesterov
2008-03-31 20:20         ` Roland McGrath
2008-03-31  8:51     ` [PATCH 1/3] do_wait reorganization Oleg Nesterov
2008-03-31 20:29       ` Roland McGrath
2008-03-31 20:07         ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080329103513.GA359@tv-sign.ru \
    --to=oleg@tv-sign.ru \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=roland@redhat.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox