summaryrefslogtreecommitdiff
path: root/fs/exec.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2004-10-18 09:12:06 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-18 09:12:06 -0700
commitd3069b4dd0767b4e24debdb21b632b2f8dd72474 (patch)
tree069671a054a203777b91dfe00e68392e4d774496 /fs/exec.c
parent7a9a3e863d834b3c9abf46b7921654f16343b5bc (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.c8
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(&current->tasks);
list_add_tail(&current->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);
}