|
@@ -44,6 +44,7 @@
|
|
|
#include <linux/userfaultfd_k.h>
|
|
|
#include <linux/moduleparam.h>
|
|
|
#include <linux/pkeys.h>
|
|
|
+#include <linux/oom.h>
|
|
|
|
|
|
#include <linux/uaccess.h>
|
|
|
#include <asm/cacheflush.h>
|
|
@@ -3001,6 +3002,23 @@ void exit_mmap(struct mm_struct *mm)
|
|
|
/* Use -1 here to ensure all VMAs in the mm are unmapped */
|
|
|
unmap_vmas(&tlb, vma, 0, -1);
|
|
|
|
|
|
+ set_bit(MMF_OOM_SKIP, &mm->flags);
|
|
|
+ if (unlikely(tsk_is_oom_victim(current))) {
|
|
|
+ /*
|
|
|
+ * Wait for oom_reap_task() to stop working on this
|
|
|
+ * mm. Because MMF_OOM_SKIP is already set before
|
|
|
+ * calling down_read(), oom_reap_task() will not run
|
|
|
+ * on this "mm" post up_write().
|
|
|
+ *
|
|
|
+ * tsk_is_oom_victim() cannot be set from under us
|
|
|
+ * either because current->mm is already set to NULL
|
|
|
+ * under task_lock before calling mmput and oom_mm is
|
|
|
+ * set not NULL by the OOM killer only if current->mm
|
|
|
+ * is found not NULL while holding the task_lock.
|
|
|
+ */
|
|
|
+ down_write(&mm->mmap_sem);
|
|
|
+ up_write(&mm->mmap_sem);
|
|
|
+ }
|
|
|
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
|
|
|
tlb_finish_mmu(&tlb, 0, -1);
|
|
|
|