All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Ratan Nalumasu <rnalumasu@gmail.com>
Cc: Roland McGrath <roland@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Ingo Molnar <mingo@elte.hu>,
	Vitaly Mayatskikh <vmayatsk@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: [rfc] do not place sub-threads on task_struct->children list
Date: Tue, 30 Jun 2009 01:08:41 +0200	[thread overview]
Message-ID: <20090629230841.GA13024@redhat.com> (raw)
In-Reply-To: <20090629033852.GA14404@redhat.com>

(change subject)

On 06/29, Oleg Nesterov wrote:
>
> On 06/25, Ratan Nalumasu wrote:
> >
> > I understood it in the _past_, but somehow forgotten the details--I have a
> > vague recollection that there was some special handling for the group leader
> > stuff.
> > However, to reconfirm, we believe that the
> > following condition in eligible_child() is good, right:
> > ===
> >        if ((wo->wo_flags & __WNOTHREAD) && wo->child_wait.private !=
> > p->parent)
> >                return 0;
> > ===
> >
> > I will run it on my test machines and see if everything looks good.
>
> OK, thanks.
>
> The only problem it uses ->parent, this conflicts with other out-of-tree
> ptrace changes...
>
> Roland, do you think we should do this change now or later?
>
> If now, then we can also do another nice optimization, and it is for free.
> See the untested patch below. It conflicts with those patches too, but
> in both cases fixups are trivial.

See the updated patch below, slightly tested.

Changes: s/reparent_thread/reparent_leader/ and move it out of loop.
We still have to check task_detached() in reparent_leader(), we can
find EXIT_DEAD leader.

Do you see any problems?

Oleg.

------------------------------------------------------------------------
[PATCH] do not place sub-threads on task_struct->children list

Currently we add sub-threads to ->real_parent->children list. This
buys nothing but slows down do_wait().

With this patch ->children contains only main threads (group leaders).
The only complication is that forget_original_parent() should iterate
over sub-threads by hand.

>From now do_wait_thread() can never see task_detached() && !EXIT_DEAD
tasks, we can remove this check (and we can unify do_wait_thread() and
ptrace_do_wait()).

This change can confuse the optimistic search inmm_update_next_owner(),
but this is fixable and minor.

Perhaps badness() and oom_kill_process() should be updated, but they
should be fixed in any case.

---

 kernel/fork.c |    2 +-
 kernel/exit.c |   41 ++++++++++++++++++++---------------------
 2 files changed, 21 insertions(+), 22 deletions(-)

--- WAIT/kernel/fork.c~3_CHILDREN_NO_THREADS	2009-06-30 00:57:16.000000000 +0200
+++ WAIT/kernel/fork.c	2009-06-30 00:57:50.000000000 +0200
@@ -1245,7 +1245,6 @@ static struct task_struct *copy_process(
 	}
 
 	if (likely(p->pid)) {
-		list_add_tail(&p->sibling, &p->real_parent->children);
 		tracehook_finish_clone(p, clone_flags, trace);
 
 		if (thread_group_leader(p)) {
@@ -1257,6 +1256,7 @@ static struct task_struct *copy_process(
 			p->signal->tty = tty_kref_get(current->signal->tty);
 			attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
 			attach_pid(p, PIDTYPE_SID, task_session(current));
+			list_add_tail(&p->sibling, &p->real_parent->children);
 			list_add_tail_rcu(&p->tasks, &init_task.tasks);
 			__get_cpu_var(process_counts)++;
 		}
--- WAIT/kernel/exit.c~3_CHILDREN_NO_THREADS	2009-06-30 00:57:16.000000000 +0200
+++ WAIT/kernel/exit.c	2009-06-30 00:57:50.000000000 +0200
@@ -67,11 +67,11 @@ static void __unhash_process(struct task
 		detach_pid(p, PIDTYPE_PGID);
 		detach_pid(p, PIDTYPE_SID);
 
+		list_del_init(&p->sibling);
 		list_del_rcu(&p->tasks);
 		__get_cpu_var(process_counts)--;
 	}
 	list_del_rcu(&p->thread_group);
-	list_del_init(&p->sibling);
 }
 
 /*
@@ -736,12 +736,9 @@ static struct task_struct *find_new_reap
 /*
 * Any that need to be release_task'd are put on the @dead list.
  */
-static void reparent_thread(struct task_struct *father, struct task_struct *p,
+static void reparent_leader(struct task_struct *father, struct task_struct *p,
 				struct list_head *dead)
 {
-	if (p->pdeath_signal)
-		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
-
 	list_move_tail(&p->sibling, &p->real_parent->children);
 
 	if (task_detached(p))
@@ -771,7 +768,7 @@ static void reparent_thread(struct task_
 
 static void forget_original_parent(struct task_struct *father)
 {
-	struct task_struct *p, *n, *reaper;
+	struct task_struct *g, *p, *n, *reaper;
 	LIST_HEAD(dead_children);
 
 	exit_ptrace(father);
@@ -779,13 +776,20 @@ static void forget_original_parent(struc
 	write_lock_irq(&tasklist_lock);
 	reaper = find_new_reaper(father);
 
-	list_for_each_entry_safe(p, n, &father->children, sibling) {
-		p->real_parent = reaper;
-		if (p->parent == father) {
-			BUG_ON(task_ptrace(p));
-			p->parent = p->real_parent;
-		}
-		reparent_thread(father, p, &dead_children);
+	list_for_each_entry_safe(g, n, &father->children, sibling) {
+		p = g;
+		do {
+			p->real_parent = reaper;
+			if (p->parent == father) {
+				BUG_ON(task_ptrace(p));
+				p->parent = p->real_parent;
+			}
+			if (p->pdeath_signal)
+				group_send_sig_info(p->pdeath_signal,
+						    SEND_SIG_NOINFO, p);
+		} while_each_thread(g, p);
+
+		reparent_leader(father, g, &dead_children);
 	}
 	write_unlock_irq(&tasklist_lock);
 
@@ -1533,14 +1537,9 @@ static int do_wait_thread(struct wait_op
 	struct task_struct *p;
 
 	list_for_each_entry(p, &tsk->children, sibling) {
-		/*
-		 * Do not consider detached threads.
-		 */
-		if (!task_detached(p)) {
-			int ret = wait_consider_task(wo, tsk, 0, p);
-			if (ret)
-				return ret;
-		}
+		int ret = wait_consider_task(wo, tsk, 0, p);
+		if (ret)
+			return ret;
 	}
 
 	return 0;


  reply	other threads:[~2009-06-29 23:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-22 17:04 [RFC,PATCH 2/2] change __wake_up_parent() to use filtered wakeup Oleg Nesterov
2009-06-24  9:13 ` Roland McGrath
2009-06-24 15:21   ` Oleg Nesterov
2009-06-24 18:57     ` Roland McGrath
2009-06-24 16:11       ` Oleg Nesterov
2009-06-24 19:42         ` Roland McGrath
2009-06-24 17:13           ` Oleg Nesterov
2009-06-24 20:51             ` Roland McGrath
     [not found]               ` <93ad5f3f0906252111n48742b9ax8dc2ad35b30f4292@mail.gmail.com>
2009-06-29  3:38                 ` Oleg Nesterov
2009-06-29 23:08                   ` Oleg Nesterov [this message]
2009-06-30 19:30                     ` [rfc] do not place sub-threads on task_struct->children list Roland McGrath
2009-07-01  5:40                       ` Oleg Nesterov
2009-06-30 19:22                   ` [RFC,PATCH 2/2] change __wake_up_parent() to use filtered wakeup 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=20090629230841.GA13024@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=rnalumasu@gmail.com \
    --cc=roland@redhat.com \
    --cc=vmayatsk@redhat.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.