diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2003-10-26 03:16:23 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-10-26 03:16:23 -0800 |
| commit | edf12049eae51473bf5050646d9b9787ee648926 (patch) | |
| tree | f4f84106112ad31eb6eb152a6a8a410e24e7cf1b | |
| parent | c2988baf02a8a29f0224115b10e575b826d5abcd (diff) | |
Add a sticky "PF_DEAD" task flag to keep track of dead processes.
Use this to simplify 'finish_task_switch', but perhaps more
importantly we can use this to track down why some processes
seem to sometimes not die properly even after having been
marked as ZOMBIE. The "task->state" flags are too fluid to
allow that well.
| -rw-r--r-- | include/linux/sched.h | 1 | ||||
| -rw-r--r-- | kernel/exit.c | 1 | ||||
| -rw-r--r-- | kernel/sched.c | 9 |
3 files changed, 5 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 4241be4f518f..031579e7e3fc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -483,6 +483,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) /* Not implemented yet, only for 486*/ #define PF_STARTING 0x00000002 /* being created */ #define PF_EXITING 0x00000004 /* getting shut down */ +#define PF_DEAD 0x00000008 /* Dead */ #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ #define PF_DUMPCORE 0x00000200 /* dumped core */ diff --git a/kernel/exit.c b/kernel/exit.c index 25b62f5971be..32f739f782d1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -688,6 +688,7 @@ static void exit_notify(struct task_struct *tsk) } tsk->state = TASK_ZOMBIE; + tsk->flags |= PF_DEAD; /* * In the preemption case it must be impossible for the task * to get runnable again, so use "_raw_" unlock to keep diff --git a/kernel/sched.c b/kernel/sched.c index 7a13a492c62d..f4e5d8e04b9c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -742,7 +742,7 @@ static inline void finish_task_switch(task_t *prev) { runqueue_t *rq = this_rq(); struct mm_struct *mm = rq->prev_mm; - int drop_task_ref; + unsigned long prev_task_flags; rq->prev_mm = NULL; @@ -757,14 +757,11 @@ static inline void finish_task_switch(task_t *prev) * be dropped twice. * Manfred Spraul <manfred@colorfullife.com> */ - drop_task_ref = 0; - if (unlikely(prev->state & (TASK_DEAD | TASK_ZOMBIE))) - drop_task_ref = 1; - + prev_task_flags = prev->flags; finish_arch_switch(rq, prev); if (mm) mmdrop(mm); - if (drop_task_ref) + if (unlikely(prev_task_flags & PF_DEAD)) put_task_struct(prev); } |
