| From 51fae6da640edf9d266c94f36bc806c63c301991 Mon Sep 17 00:00:00 2001 |
| From: Cong Wang <xiyou.wangcong@gmail.com> |
| Date: Tue, 21 Oct 2014 09:27:12 +0200 |
| Subject: freezer: Do not freeze tasks killed by OOM killer |
| |
| From: Cong Wang <xiyou.wangcong@gmail.com> |
| |
| commit 51fae6da640edf9d266c94f36bc806c63c301991 upstream. |
| |
| Since f660daac474c6f (oom: thaw threads if oom killed thread is frozen |
| before deferring) OOM killer relies on being able to thaw a frozen task |
| to handle OOM situation but a3201227f803 (freezer: make freezing() test |
| freeze conditions in effect instead of TIF_FREEZE) has reorganized the |
| code and stopped clearing freeze flag in __thaw_task. This means that |
| the target task only wakes up and goes into the fridge again because the |
| freezing condition hasn't changed for it. This reintroduces the bug |
| fixed by f660daac474c6f. |
| |
| Fix the issue by checking for TIF_MEMDIE thread flag in |
| freezing_slow_path and exclude the task from freezing completely. If a |
| task was already frozen it would get woken by __thaw_task from OOM killer |
| and get out of freezer after rechecking freezing(). |
| |
| Changes since v1 |
| - put TIF_MEMDIE check into freezing_slowpath rather than in __refrigerator |
| as per Oleg |
| - return __thaw_task into oom_scan_process_thread because |
| oom_kill_process will not wake task in the fridge because it is |
| sleeping uninterruptible |
| |
| [mhocko@suse.cz: rewrote the changelog] |
| Fixes: a3201227f803 (freezer: make freezing() test freeze conditions in effect instead of TIF_FREEZE) |
| Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> |
| Signed-off-by: Michal Hocko <mhocko@suse.cz> |
| Acked-by: Oleg Nesterov <oleg@redhat.com> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| kernel/freezer.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/kernel/freezer.c |
| +++ b/kernel/freezer.c |
| @@ -42,6 +42,9 @@ bool freezing_slow_path(struct task_stru |
| if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK)) |
| return false; |
| |
| + if (test_thread_flag(TIF_MEMDIE)) |
| + return false; |
| + |
| if (pm_nosig_freezing || cgroup_freezing(p)) |
| return true; |
| |