diff options
author | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:23 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-11-21 15:32:23 -0500 |
commit | a585042f7b933539a0b6bc63650c2d49ffb2e55d (patch) | |
tree | bb93d05050e04c4bcd53fdf535239e6312fb62e2 | |
parent | a5be2d0d1a8746e7be5210e3d6b904455000443c (diff) |
freezer: remove racy clear_freeze_flag() and set PF_NOFREEZE on dead tasks
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>
-rw-r--r-- | kernel/exit.c | 3 | ||||
-rw-r--r-- | kernel/power/process.c | 3 |
2 files changed, 2 insertions, 4 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index d0b7d988f873..95a4141d07e7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -679,8 +679,6 @@ static void exit_mm(struct task_struct * tsk) | |||
679 | tsk->mm = NULL; | 679 | tsk->mm = NULL; |
680 | up_read(&mm->mmap_sem); | 680 | up_read(&mm->mmap_sem); |
681 | enter_lazy_tlb(mm, current); | 681 | enter_lazy_tlb(mm, current); |
682 | /* We don't want this task to be frozen prematurely */ | ||
683 | clear_freeze_flag(tsk); | ||
684 | task_unlock(tsk); | 682 | task_unlock(tsk); |
685 | mm_update_next_owner(mm); | 683 | mm_update_next_owner(mm); |
686 | mmput(mm); | 684 | mmput(mm); |
@@ -1040,6 +1038,7 @@ NORET_TYPE void do_exit(long code) | |||
1040 | exit_rcu(); | 1038 | exit_rcu(); |
1041 | /* causes final put_task_struct in finish_task_switch(). */ | 1039 | /* causes final put_task_struct in finish_task_switch(). */ |
1042 | tsk->state = TASK_DEAD; | 1040 | tsk->state = TASK_DEAD; |
1041 | tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */ | ||
1043 | schedule(); | 1042 | schedule(); |
1044 | BUG(); | 1043 | BUG(); |
1045 | /* Avoid "noreturn function does return". */ | 1044 | /* Avoid "noreturn function does return". */ |
diff --git a/kernel/power/process.c b/kernel/power/process.c index fe2787207f00..23822dc14b6c 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -25,8 +25,7 @@ | |||
25 | static inline int freezable(struct task_struct * p) | 25 | static inline int freezable(struct task_struct * p) |
26 | { | 26 | { |
27 | if ((p == current) || | 27 | if ((p == current) || |
28 | (p->flags & PF_NOFREEZE) || | 28 | (p->flags & PF_NOFREEZE)) |
29 | (p->exit_state != 0)) | ||
30 | return 0; | 29 | return 0; |
31 | return 1; | 30 | return 1; |
32 | } | 31 | } |