lkml.org 
[lkml]   [2005]   [Dec]   [24]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateSat, 24 Dec 2005 20:52:54 +0300
FromOleg Nesterov <>
SubjectRe: [rfc][patch] Avoid taking global tasklist_lock for single threaded process at getrusage()
Ravikiran G Thirumalai wrote:
>
> +int getrusage_both(struct task_struct *p, struct rusage __user *ru)
>  {
> +	unsigned long flags;
> +	int lockflag = 0;
> +	cputime_t utime, stime;
>  	struct rusage r;
> -	read_lock(&tasklist_lock);
> -	k_getrusage(p, who, &r);
> -	read_unlock(&tasklist_lock);
> +	struct task_struct *t;
> +	memset((char *) &r, 0, sizeof (r));
> +
> +	if (unlikely(!p->signal))
> +		 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
> +
> +	if (!thread_group_empty(p)) {
> +		read_lock(&tasklist_lock);
> +		lockflag = 1;
> +	}

I can't understand this. 'p' can do clone(CLONE_THREAD) immediately
after 'if (!thread_group_empty(p))' check.
> +	spin_lock_irqsave(&p->sighand->siglock, flags);

It is unsafe to do (unless p == current or tasklist held) even if
'p' is the only one process in the thread group.

p->sighand can be changed (and even freed) if 'p' does exec, see
de_thread().

p->sighand may be NULL , nothing prevents 'p' from release_task(p).
This patch checks p->signal, but this is meaningless unless it was
done under tasklist_lock.

Oleg.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-12-24 17:40    [from the cache]
©2003-2008