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 @@ | |||
40 | #include <linux/ratelimit.h> | 40 | #include <linux/ratelimit.h> |
41 | #include <linux/kthread.h> | 41 | #include <linux/kthread.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/mmu_notifier.h> | ||
43 | 44 | ||
44 | #include <asm/tlb.h> | 45 | #include <asm/tlb.h> |
45 | #include "internal.h" | 46 | #include "internal.h" |
@@ -495,6 +496,21 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | |||
495 | } | 496 | } |
496 | 497 | ||
497 | /* | 498 | /* |
499 | * If the mm has notifiers then we would need to invalidate them around | ||
500 | * unmap_page_range and that is risky because notifiers can sleep and | ||
501 | * what they do is basically undeterministic. So let's have a short | ||
502 | * sleep to give the oom victim some more time. | ||
503 | * TODO: we really want to get rid of this ugly hack and make sure that | ||
504 | * notifiers cannot block for unbounded amount of time and add | ||
505 | * mmu_notifier_invalidate_range_{start,end} around unmap_page_range | ||
506 | */ | ||
507 | if (mm_has_notifiers(mm)) { | ||
508 | up_read(&mm->mmap_sem); | ||
509 | schedule_timeout_idle(HZ); | ||
510 | goto unlock_oom; | ||
511 | } | ||
512 | |||
513 | /* | ||
498 | * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't | 514 | * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't |
499 | * work on the mm anymore. The check for MMF_OOM_SKIP must run | 515 | * work on the mm anymore. The check for MMF_OOM_SKIP must run |
500 | * under mmap_sem for reading because it serializes against the | 516 | * under mmap_sem for reading because it serializes against the |