--- /dev/null
+From b2b2cbc4b2a2f389442549399a993a8306420baf Mon Sep 17 00:00:00 2001
+From: Eric W. Biederman <ebiederm@xmission.com>
+Date: Thu, 21 Dec 2006 21:28:40 -0700
+Subject: [PATCH] Fix reparenting to the same thread group. (take 2)
+
+This patch fixes the case when we reparent to a different thread in the
+same thread group. This modifies the code so that we do not send
+signals and do not change the signal to send to SIGCHLD unless we have
+change the thread group of our parents. It also suppresses sending
+pdeath_sig in this cas as well since the result of geppid doesn't
+change.
+
+Thanks to Oleg for spotting my bug of only fixing this for non-ptraced
+tasks.
+
+Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Albert Cahalan <acahalan@gmail.com>
+Cc: Andrew Morton <akpm@osdl.org>
+Cc: Roland McGrath <roland@redhat.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Coywolf Qi Hunt <qiyong@fc-cn.com>
+Acked-by: Oleg Nesterov <oleg@tv-sign.ru>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+[chrisw: fold in 241ceee0b442, Oleg's fix to restore user visible behaviour]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ kernel/exit.c | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+--- linux-2.6.19.2.orig/kernel/exit.c
++++ linux-2.6.19.2/kernel/exit.c
+@@ -603,10 +603,6 @@ choose_new_parent(struct task_struct *p,
+ static void
+ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
+ {
+- /* We don't want people slaying init. */
+- if (p->exit_signal != -1)
+- p->exit_signal = SIGCHLD;
+-
+ if (p->pdeath_signal)
+ /* We already hold the tasklist_lock here. */
+ group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
+@@ -626,13 +622,7 @@ reparent_thread(struct task_struct *p, s
+ p->parent = p->real_parent;
+ add_parent(p);
+
+- /* If we'd notified the old parent about this child's death,
+- * also notify the new parent.
+- */
+- if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
+- thread_group_empty(p))
+- do_notify_parent(p, p->exit_signal);
+- else if (p->state == TASK_TRACED) {
++ if (p->state == TASK_TRACED) {
+ /*
+ * If it was at a trace stop, turn it into
+ * a normal stop since it's no longer being
+@@ -642,6 +632,23 @@ reparent_thread(struct task_struct *p, s
+ }
+ }
+
++ /* If this is a threaded reparent there is no need to
++ * notify anyone anything has happened.
++ */
++ if (p->real_parent->group_leader == father->group_leader)
++ return;
++
++ /* We don't want people slaying init. */
++ if (p->exit_signal != -1)
++ p->exit_signal = SIGCHLD;
++
++ /* If we'd notified the old parent about this child's death,
++ * also notify the new parent.
++ */
++ if (!traced && p->exit_state == EXIT_ZOMBIE &&
++ p->exit_signal != -1 && thread_group_empty(p))
++ do_notify_parent(p, p->exit_signal);
++
+ /*
+ * process group orphan check
+ * Case ii: Our child is in a different pgrp