|
@@ -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"
|
|
@@ -494,6 +495,21 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
|
|
|
goto unlock_oom;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * 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
|