Re: [patch] Re: Problem with exiting threads under NPTL

Ingo Molnar
2003-12-14T21:03:17Z

On Sun, 14 Dec 2003, Linus Torvalds wrote:

> Btw, on another note: to avoid the appearance of recursion, I'd prefer a
>
> p = leader;
> goto top;
>
> instead of a "release_task(leader);".
>
> I realize that the recursion should be just one deep (the leader of the
> leader is itself, and that will stop the thing from going further), but
> it looks trivial to avoid it, and any automated source checking tool
> would be confused by the apparent recursion.

yeah. New (SMP-testbooted) patch attached. I also got rid of the
zap_leader flag. (we can signal leader-zapping via the leader pointer.)

Ingo

--- linux/kernel/exit.c.orig
+++ linux/kernel/exit.c
@@ -51,7 +51,8 @@ void release_task(struct task_struct * p
{
task_t *leader;
struct dentry *proc_dentry;
-
+
+restart:
BUG_ON(p->state < TASK_ZOMBIE);

atomic_dec(&p->user->processes);
@@ -72,8 +73,20 @@ void release_task(struct task_struct * p
*/
leader = p->group_leader;
if (leader != p && thread_group_empty(leader) &&
- leader->state == TASK_ZOMBIE && leader->exit_signal != -1)
+ leader->state == TASK_ZOMBIE && leader->exit_signal != -1) {
do_notify_parent(leader, leader->exit_signal);
+ /*
+ * If we were the last child thread and the leader has
+ * exited already, and the leader's parent ignores SIGCHLD,
+ * then we are the one who should release the leader.
+ *
+ * (non-NULL leader triggers the zapping of the leader at
+ * the end of this function.)
+ */
+ if (leader->exit_signal != -1)
+ leader = NULL;
+ } else
+ leader = NULL;

p->parent->cutime += p->utime + p->cutime;
p->parent->cstime += p->stime + p->cstime;
@@ -88,6 +101,16 @@ void release_task(struct task_struct * p
proc_pid_flush(proc_dentry);
release_thread(p);
put_task_struct(p);
+
+ /*
+ * Do this outside the tasklist lock. The reference to the
+ * leader is safe. There's no recursion possible, since
+ * the leader of the leader is itself:
+ */
+ if (unlikely(leader)) {
+ p = leader;
+ goto restart;
+ }
}

/* we are using it only for SMP init */