arch: mm: do not invoke OOM killer on kernel fault OOM

Kernel faults are expected to handle OOM conditions gracefully (gup,
uaccess etc.), so they should never invoke the OOM killer.  Reserve this
for faults triggered in user context when it is the only option.

Most architectures already do this, fix up the remaining few.

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: David Rientjes <rientjes@google.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: azurIt <azurit@pobox.sk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Johannes Weiner 2013-09-12 15:13:38 -07:00 committed by Linus Torvalds
parent 94bce453c7
commit 871341023c
6 changed files with 26 additions and 22 deletions

View File

@ -349,6 +349,13 @@ retry:
if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
return 0; return 0;
/*
* If we are in kernel mode at this point, we
* have no context to handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_OOM) { if (fault & VM_FAULT_OOM) {
/* /*
* We ran out of memory, call the OOM killer, and return to * We ran out of memory, call the OOM killer, and return to
@ -359,13 +366,6 @@ retry:
return 0; return 0;
} }
/*
* If we are in kernel mode at this point, we
* have no context to handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_SIGBUS) { if (fault & VM_FAULT_SIGBUS) {
/* /*
* We had some memory, but were unable to * We had some memory, but were unable to

View File

@ -288,6 +288,13 @@ retry:
VM_FAULT_BADACCESS)))) VM_FAULT_BADACCESS))))
return 0; return 0;
/*
* If we are in kernel mode at this point, we have no context to
* handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_OOM) { if (fault & VM_FAULT_OOM) {
/* /*
* We ran out of memory, call the OOM killer, and return to * We ran out of memory, call the OOM killer, and return to
@ -298,13 +305,6 @@ retry:
return 0; return 0;
} }
/*
* If we are in kernel mode at this point, we have no context to
* handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_SIGBUS) { if (fault & VM_FAULT_SIGBUS) {
/* /*
* We had some memory, but were unable to successfully fix up * We had some memory, but were unable to successfully fix up

View File

@ -228,9 +228,9 @@ no_context:
*/ */
out_of_memory: out_of_memory:
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
pagefault_out_of_memory();
if (!user_mode(regs)) if (!user_mode(regs))
goto no_context; goto no_context;
pagefault_out_of_memory();
return; return;
do_sigbus: do_sigbus:

View File

@ -241,6 +241,8 @@ out_of_memory:
* (which will retry the fault, or kill us if we got oom-killed). * (which will retry the fault, or kill us if we got oom-killed).
*/ */
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (!user_mode(regs))
goto no_context;
pagefault_out_of_memory(); pagefault_out_of_memory();
return; return;

View File

@ -124,6 +124,8 @@ out_of_memory:
* (which will retry the fault, or kill us if we got oom-killed). * (which will retry the fault, or kill us if we got oom-killed).
*/ */
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (!is_user)
goto out_nosemaphore;
pagefault_out_of_memory(); pagefault_out_of_memory();
return 0; return 0;
} }

View File

@ -278,6 +278,13 @@ retry:
(VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
return 0; return 0;
/*
* If we are in kernel mode at this point, we
* have no context to handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_OOM) { if (fault & VM_FAULT_OOM) {
/* /*
* We ran out of memory, call the OOM killer, and return to * We ran out of memory, call the OOM killer, and return to
@ -288,13 +295,6 @@ retry:
return 0; return 0;
} }
/*
* If we are in kernel mode at this point, we
* have no context to handle this fault with.
*/
if (!user_mode(regs))
goto no_context;
if (fault & VM_FAULT_SIGBUS) { if (fault & VM_FAULT_SIGBUS) {
/* /*
* We had some memory, but were unable to * We had some memory, but were unable to