Commit edf12049 authored by Linus Torvalds's avatar Linus Torvalds

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.
parent c2988baf
...@@ -483,6 +483,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) ...@@ -483,6 +483,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
/* Not implemented yet, only for 486*/ /* Not implemented yet, only for 486*/
#define PF_STARTING 0x00000002 /* being created */ #define PF_STARTING 0x00000002 /* being created */
#define PF_EXITING 0x00000004 /* getting shut down */ #define PF_EXITING 0x00000004 /* getting shut down */
#define PF_DEAD 0x00000008 /* Dead */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_DUMPCORE 0x00000200 /* dumped core */
......
...@@ -688,6 +688,7 @@ static void exit_notify(struct task_struct *tsk) ...@@ -688,6 +688,7 @@ static void exit_notify(struct task_struct *tsk)
} }
tsk->state = TASK_ZOMBIE; tsk->state = TASK_ZOMBIE;
tsk->flags |= PF_DEAD;
/* /*
* In the preemption case it must be impossible for the task * In the preemption case it must be impossible for the task
* to get runnable again, so use "_raw_" unlock to keep * to get runnable again, so use "_raw_" unlock to keep
......
...@@ -742,7 +742,7 @@ static inline void finish_task_switch(task_t *prev) ...@@ -742,7 +742,7 @@ static inline void finish_task_switch(task_t *prev)
{ {
runqueue_t *rq = this_rq(); runqueue_t *rq = this_rq();
struct mm_struct *mm = rq->prev_mm; struct mm_struct *mm = rq->prev_mm;
int drop_task_ref; unsigned long prev_task_flags;
rq->prev_mm = NULL; rq->prev_mm = NULL;
...@@ -757,14 +757,11 @@ static inline void finish_task_switch(task_t *prev) ...@@ -757,14 +757,11 @@ static inline void finish_task_switch(task_t *prev)
* be dropped twice. * be dropped twice.
* Manfred Spraul <manfred@colorfullife.com> * Manfred Spraul <manfred@colorfullife.com>
*/ */
drop_task_ref = 0; prev_task_flags = prev->flags;
if (unlikely(prev->state & (TASK_DEAD | TASK_ZOMBIE)))
drop_task_ref = 1;
finish_arch_switch(rq, prev); finish_arch_switch(rq, prev);
if (mm) if (mm)
mmdrop(mm); mmdrop(mm);
if (drop_task_ref) if (unlikely(prev_task_flags & PF_DEAD))
put_task_struct(prev); put_task_struct(prev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment