]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
freezer: remove racy clear_freeze_flag() and set PF_NOFREEZE on dead tasks
authorTejun Heo <tj@kernel.org>
Mon, 31 Oct 2011 22:30:30 +0000 (15:30 -0700)
committerTejun Heo <tj@kernel.org>
Mon, 31 Oct 2011 22:30:30 +0000 (15:30 -0700)
clear_freeze_flag() in exit_mm() is racy.  Freezing can start
afterwards.  Remove it.  Skipping freezer for exiting task will be
properly implemented later.

Also, freezable() was testing exit_state directly to make system
freezer ignore dead tasks.  Let the exiting task set PF_NOFREEZE after
entering TASK_DEAD instead.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
kernel/exit.c
kernel/power/process.c

index 2913b3509d4288026990cc087894e69eace6c564..3d6f570267f9d987a3719169ae8774d1853a1391 100644 (file)
@@ -679,8 +679,6 @@ static void exit_mm(struct task_struct * tsk)
        tsk->mm = NULL;
        up_read(&mm->mmap_sem);
        enter_lazy_tlb(mm, current);
-       /* We don't want this task to be frozen prematurely */
-       clear_freeze_flag(tsk);
        if (tsk->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
                atomic_dec(&mm->oom_disable_count);
        task_unlock(tsk);
@@ -1042,6 +1040,7 @@ NORET_TYPE void do_exit(long code)
        exit_rcu();
        /* causes final put_task_struct in finish_task_switch(). */
        tsk->state = TASK_DEAD;
+       tsk->flags |= PF_NOFREEZE;      /* tell freezer to ignore us */
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
index fe2787207f00d665371ca72a57c3508d2cdbd000..23822dc14b6c14e61b718053cdee5d044e2bdc76 100644 (file)
@@ -25,8 +25,7 @@
 static inline int freezable(struct task_struct * p)
 {
        if ((p == current) ||
-           (p->flags & PF_NOFREEZE) ||
-           (p->exit_state != 0))
+           (p->flags & PF_NOFREEZE))
                return 0;
        return 1;
 }