aboutsummaryrefslogtreecommitdiffstats
path: root/mm/oom_kill.c
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.com>2016-05-20 19:57:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commitec8d7c14ea14922fe21945b458a75e39f11dd832 (patch)
treefe45cbd94518218d2be1288a812dbca8c1e01d95 /mm/oom_kill.c
parentbb8a4b7fd1266ef888b3a80aa5f266062b224ef4 (diff)
mm, oom_reaper: do not mmput synchronously from the oom reaper context
Tetsuo has properly noted that mmput slow path might get blocked waiting for another party (e.g. exit_aio waits for an IO). If that happens the oom_reaper would be put out of the way and will not be able to process next oom victim. We should strive for making this context as reliable and independent on other subsystems as much as possible. Introduce mmput_async which will perform the slow path from an async (WQ) context. This will delay the operation but that shouldn't be a problem because the oom_reaper has reclaimed the victim's address space for most cases as much as possible and the remaining context shouldn't bind too much memory anymore. The only exception is when mmap_sem trylock has failed which shouldn't happen too often. The issue is only theoretical but not impossible. Signed-off-by: Michal Hocko <mhocko@suse.com> Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: David Rientjes <rientjes@google.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.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index c0376efa79ec..c0e37dd1422f 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -446,7 +446,6 @@ static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);
446static struct task_struct *oom_reaper_list; 446static struct task_struct *oom_reaper_list;
447static DEFINE_SPINLOCK(oom_reaper_lock); 447static DEFINE_SPINLOCK(oom_reaper_lock);
448 448
449
450static bool __oom_reap_task(struct task_struct *tsk) 449static bool __oom_reap_task(struct task_struct *tsk)
451{ 450{
452 struct mmu_gather tlb; 451 struct mmu_gather tlb;
@@ -520,7 +519,12 @@ static bool __oom_reap_task(struct task_struct *tsk)
520 */ 519 */
521 set_bit(MMF_OOM_REAPED, &mm->flags); 520 set_bit(MMF_OOM_REAPED, &mm->flags);
522out: 521out:
523 mmput(mm); 522 /*
523 * Drop our reference but make sure the mmput slow path is called from a
524 * different context because we shouldn't risk we get stuck there and
525 * put the oom_reaper out of the way.
526 */
527 mmput_async(mm);
524 return ret; 528 return ret;
525} 529}
526 530