From 3fb45733dfb37694452381bf1d9183bb6f93ee35 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 20 Aug 2011 11:31:39 +0200 Subject: [PATCH] freezer: make exiting tasks properly unfreezable There's no point in freezing an exiting task. The current code seemingly tries that by calling clear_freeze_flag() from exit_mm() but it's racy as freeze might happen afterwards. This patch removes the racy clear_freeze_flag() makes do_exit() set PF_NOFREEZE after PTRACE_EVENT_EXIT, after which freezing doesn't make sense. Signed-off-by: Tejun Heo --- kernel/exit.c | 8 ++++++-- kernel/power/process.c | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 2913b3509d42..ac58259a9f8a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -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); @@ -915,6 +913,12 @@ NORET_TYPE void do_exit(long code) ptrace_event(PTRACE_EVENT_EXIT, code); + /* + * With ptrace notification done, there's no point in freezing from + * here on. Disallow freezing. + */ + current->flags |= PF_NOFREEZE; + validate_creds_for_do_exit(tsk); /* diff --git a/kernel/power/process.c b/kernel/power/process.c index bec09c392d81..ddfaba4da2b1 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -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; } -- 2.39.5