]> git.hungrycats.org Git - linux/commitdiff
Add a sticky "PF_DEAD" task flag to keep track of dead processes.
authorLinus Torvalds <torvalds@home.osdl.org>
Sun, 26 Oct 2003 11:16:23 +0000 (03:16 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 26 Oct 2003 11:16:23 +0000 (03:16 -0800)
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.

include/linux/sched.h
kernel/exit.c
kernel/sched.c

index 4241be4f518f802cd7ab16719c7cf9efb056ac9a..031579e7e3fc5d44f2314e5833b0e349fda5e707 100644 (file)
@@ -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 */
index 25b62f5971be614d7d3112cce2a068f81ecab5a1..32f739f782d133ebe6387b403257a69778a80e0a 100644 (file)
@@ -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
index 7a13a492c62d509178d1c5687ba88b2bc7c886cd..f4e5d8e04b9cde48c1a8af00fe7c1ba6685ef583 100644 (file)
@@ -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);
 }