aboutsummaryrefslogtreecommitdiffstats
path: root/mm/oom_kill.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2015-02-11 18:24:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 20:06:00 -0500
commitd7a94e7e11badf8404d40b41e008c3131a3cebe3 (patch)
tree0f8a7c3cf1bfd7945740bc67f1607e6923b2186d /mm/oom_kill.c
parent56873f43abdcd574b25105867a990f067747b2f4 (diff)
oom: don't count on mm-less current process
out_of_memory() doesn't trigger the OOM killer if the current task is already exiting or it has fatal signals pending, and gives the task access to memory reserves instead. However, doing so is wrong if out_of_memory() is called by an allocation (e.g. from exit_task_work()) after the current task has already released its memory and cleared TIF_MEMDIE at exit_mm(). If we again set TIF_MEMDIE to post-exit_mm() current task, the OOM killer will be blocked by the task sitting in the final schedule() waiting for its parent to reap it. It will trigger an OOM livelock if its parent is unable to reap it due to doing an allocation and waiting for the OOM killer to kill it. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Acked-by: Michal Hocko <mhocko@suse.cz> Cc: David Rientjes <rientjes@google.com> Cc: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r--mm/oom_kill.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index d503e9ce1c7b..f82dd13cca68 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -643,8 +643,12 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
643 * If current has a pending SIGKILL or is exiting, then automatically 643 * If current has a pending SIGKILL or is exiting, then automatically
644 * select it. The goal is to allow it to allocate so that it may 644 * select it. The goal is to allow it to allocate so that it may
645 * quickly exit and free its memory. 645 * quickly exit and free its memory.
646 *
647 * But don't select if current has already released its mm and cleared
648 * TIF_MEMDIE flag at exit_mm(), otherwise an OOM livelock may occur.
646 */ 649 */
647 if (fatal_signal_pending(current) || task_will_free_mem(current)) { 650 if (current->mm &&
651 (fatal_signal_pending(current) || task_will_free_mem(current))) {
648 set_thread_flag(TIF_MEMDIE); 652 set_thread_flag(TIF_MEMDIE);
649 return; 653 return;
650 } 654 }