diff options
| author | Ingo Molnar <mingo@elte.hu> | 2004-10-18 09:12:06 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-18 09:12:06 -0700 |
| commit | d3069b4dd0767b4e24debdb21b632b2f8dd72474 (patch) | |
| tree | 069671a054a203777b91dfe00e68392e4d774496 /fs/exec.c | |
| parent | 7a9a3e863d834b3c9abf46b7921654f16343b5bc (diff) | |
[PATCH] fix & clean up zombie/dead task handling & preemption
This patch fixes all the preempt-after-task->state-is-TASK_DEAD problems we
had. Right now, the moment procfs does a down() that sleeps in
proc_pid_flush() [it could] our TASK_DEAD state is zapped and we might be
back to TASK_RUNNING to and we trigger this assert:
schedule();
BUG();
/* Avoid "noreturn function does return". */
for (;;) ;
I have split out TASK_ZOMBIE and TASK_DEAD into a separate p->exit_state
field, to allow the detaching of exit-signal/parent/wait-handling from
descheduling a dead task. Dead-task freeing is done via PF_DEAD.
Tested the patch on x86 SMP and UP, but all architectures should work
fine.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/exec.c b/fs/exec.c index 125a04e3692b..e715541b2db4 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -632,14 +632,14 @@ static inline int de_thread(struct task_struct *tsk) if (current->pid != current->tgid) { struct task_struct *leader = current->group_leader, *parent; struct dentry *proc_dentry1, *proc_dentry2; - unsigned long state, ptrace; + unsigned long exit_state, ptrace; /* * Wait for the thread group leader to be a zombie. * It should already be zombie at this point, most * of the time. */ - while (leader->state != TASK_ZOMBIE) + while (leader->exit_state != EXIT_ZOMBIE) yield(); spin_lock(&leader->proc_lock); @@ -683,7 +683,7 @@ static inline int de_thread(struct task_struct *tsk) list_del(¤t->tasks); list_add_tail(¤t->tasks, &init_task.tasks); current->exit_signal = SIGCHLD; - state = leader->state; + exit_state = leader->exit_state; write_unlock_irq(&tasklist_lock); spin_unlock(&leader->proc_lock); @@ -691,7 +691,7 @@ static inline int de_thread(struct task_struct *tsk) proc_pid_flush(proc_dentry1); proc_pid_flush(proc_dentry2); - if (state != TASK_ZOMBIE) + if (exit_state != EXIT_ZOMBIE) BUG(); release_task(leader); } |
