diff options
Diffstat (limited to 'mm/oom_kill.c')
| -rw-r--r-- | mm/oom_kill.c | 16 | 
1 files changed, 16 insertions, 0 deletions
| diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 99736e026712..dee0f75c3013 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -40,6 +40,7 @@  #include <linux/ratelimit.h>  #include <linux/kthread.h>  #include <linux/init.h> +#include <linux/mmu_notifier.h>  #include <asm/tlb.h>  #include "internal.h" @@ -495,6 +496,21 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)  	}  	/* +	 * If the mm has notifiers then we would need to invalidate them around +	 * unmap_page_range and that is risky because notifiers can sleep and +	 * what they do is basically undeterministic.  So let's have a short +	 * sleep to give the oom victim some more time. +	 * TODO: we really want to get rid of this ugly hack and make sure that +	 * notifiers cannot block for unbounded amount of time and add +	 * mmu_notifier_invalidate_range_{start,end} around unmap_page_range +	 */ +	if (mm_has_notifiers(mm)) { +		up_read(&mm->mmap_sem); +		schedule_timeout_idle(HZ); +		goto unlock_oom; +	} + +	/*  	 * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't  	 * work on the mm anymore. The check for MMF_OOM_SKIP must run  	 * under mmap_sem for reading because it serializes against the |