Skip to content

Commit

Permalink
arch: mm: do not invoke OOM killer on kernel fault OOM
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Weiner authored and Linus Torvalds committed Sep 12, 2013
1 parent 94bce45 commit 8713410
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 22 deletions.
14 changes: 7 additions & 7 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,13 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
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) {
/*
* We ran out of memory, call the OOM killer, and return to
Expand All @@ -359,13 +366,6 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
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) {
/*
* We had some memory, but were unable to
Expand Down
14 changes: 7 additions & 7 deletions arch/arm64/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,13 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
VM_FAULT_BADACCESS))))
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) {
/*
* We ran out of memory, call the OOM killer, and return to
Expand All @@ -298,13 +305,6 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
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) {
/*
* We had some memory, but were unable to successfully fix up
Expand Down
2 changes: 1 addition & 1 deletion arch/avr32/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
*/
out_of_memory:
up_read(&mm->mmap_sem);
pagefault_out_of_memory();
if (!user_mode(regs))
goto no_context;
pagefault_out_of_memory();
return;

do_sigbus:
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
* (which will retry the fault, or kill us if we got oom-killed).
*/
up_read(&mm->mmap_sem);
if (!user_mode(regs))
goto no_context;
pagefault_out_of_memory();
return;

Expand Down
2 changes: 2 additions & 0 deletions arch/um/kernel/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
* (which will retry the fault, or kill us if we got oom-killed).
*/
up_read(&mm->mmap_sem);
if (!is_user)
goto out_nosemaphore;
pagefault_out_of_memory();
return 0;
}
Expand Down
14 changes: 7 additions & 7 deletions arch/unicore32/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,13 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
(VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
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) {
/*
* We ran out of memory, call the OOM killer, and return to
Expand All @@ -288,13 +295,6 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
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) {
/*
* We had some memory, but were unable to
Expand Down

0 comments on commit 8713410

Please sign in to comment.