All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	"Zhang, Yanmin" <yanmin_zhang@linux.intel.com>,
	LKML <linux-kernel@vger.kernel.org>,
	andi.kleen@intel.com, stable@kernel.org
Subject: Re: [PATCH] Don't apply for write lock on tasklist_lock if parent doesn't ptrace other processes
Date: Thu, 22 Jul 2010 11:05:24 +0200	[thread overview]
Message-ID: <20100722090524.GA6647@redhat.com> (raw)
In-Reply-To: <20100721222529.EFBAA400B6@magilla.sf.frob.com>

I am not surpized perf blaims tasklist, but I am really surpized this patch
adds 10% improvement...

On 07/21, Roland McGrath wrote:
>
> > > @@ -331,6 +331,9 @@ void exit_ptrace(struct task_struct *tra
> > >  	struct task_struct *p, *n;
> > >  	LIST_HEAD(ptrace_dead);
> > >
> > > +	if (list_empty(&tracer->ptraced))
> > > +		return;
> > > +
> > >  	write_lock_irq(&tasklist_lock);
> > >  	list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
> > >  		if (__ptrace_detach(tracer, p))
>
> I think we may have tried that before.  Oleg can tell us if it's really
> safe vs a race with PTRACE_TRACEME or something like that.

Yes, this can race with ptrace_traceme(). Without tasklist_lock in
exit_ptrace(), it is possible that ptrace_traceme() starts __ptrace_link()
before it sees PF_EXITING, and completes before the result of list_add()
is visible to the exiting parent. tasklist acts as a barrier.

So, this list_empty() check needs taskslit at least for reading. But, we
are going to take it for writing right after exit_ptrace() returns, afaics
we can add this fastpatch check for free.

Uncompiled/untested.

Oleg.

 kernel/ptrace.c |   10 +++++++---
 kernel/exit.c   |    3 ++-
 2 files changed, 9 insertions(+), 4 deletions(-)

--- x/kernel/ptrace.c
+++ x/kernel/ptrace.c
@@ -324,26 +324,30 @@ int ptrace_detach(struct task_struct *ch
 }
 
 /*
- * Detach all tasks we were using ptrace on.
+ * Detach all tasks we were using ptrace on. Called with tasklist held.
  */
 void exit_ptrace(struct task_struct *tracer)
 {
 	struct task_struct *p, *n;
 	LIST_HEAD(ptrace_dead);
 
-	write_lock_irq(&tasklist_lock);
+	if (likely(list_empty(&tracer->ptraced)))
+		return;
+
 	list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
 		if (__ptrace_detach(tracer, p))
 			list_add(&p->ptrace_entry, &ptrace_dead);
 	}
-	write_unlock_irq(&tasklist_lock);
 
+	write_unlock_irq(&tasklist_lock);
 	BUG_ON(!list_empty(&tracer->ptraced));
 
 	list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) {
 		list_del_init(&p->ptrace_entry);
 		release_task(p);
 	}
+
+	write_lock_irq(&tasklist_lock);
 }
 
 int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len)
--- x/kernel/exit.c
+++ x/kernel/exit.c
@@ -771,9 +771,10 @@ static void forget_original_parent(struc
 	struct task_struct *p, *n, *reaper;
 	LIST_HEAD(dead_children);
 
+	write_lock_irq(&tasklist_lock);
+
 	exit_ptrace(father);
 
-	write_lock_irq(&tasklist_lock);
 	reaper = find_new_reaper(father);
 
 	list_for_each_entry_safe(p, n, &father->children, sibling) {


  reply	other threads:[~2010-07-22  9:08 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-15  6:51 [PATCH] Don't apply for write lock on tasklist_lock if parent doesn't ptrace other processes Zhang, Yanmin
2010-07-15 19:53 ` David Rientjes
2010-07-21 21:49 ` Andrew Morton
2010-07-21 22:25   ` Roland McGrath
2010-07-22  9:05     ` Oleg Nesterov [this message]
2010-07-22 19:24       ` Roland McGrath
2010-07-23 17:40         ` Oleg Nesterov
2010-07-23  8:45       ` Zhang, Yanmin
2010-07-23 17:34         ` Oleg Nesterov
2010-07-26  5:05           ` Zhang, Yanmin
2010-07-26  8:53             ` Oleg Nesterov
2010-07-26  9:40               ` Kleen, Andi
2010-07-27  1:15               ` Zhang, Yanmin
2010-07-29 15:12                 ` [PATCH] ptrace: optimize exit_ptrace() for the likely case Oleg Nesterov
2010-07-29 17:40                   ` Roland McGrath

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=20100722090524.GA6647@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi.kleen@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=roland@redhat.com \
    --cc=stable@kernel.org \
    --cc=yanmin_zhang@linux.intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.