diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-20 12:47:40 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-20 12:55:49 +0100 |
commit | b42c6344b091db680fd1ec7a0483e8b6796f802b (patch) | |
tree | 37b25ae64b025dfbf041630e4d4b26b63b0a217f /arch/arm/mm | |
parent | c88d6aa71bd2ad7b4da2f281bd64ada65d533d83 (diff) | |
download | op-kernel-dev-b42c6344b091db680fd1ec7a0483e8b6796f802b.zip op-kernel-dev-b42c6344b091db680fd1ec7a0483e8b6796f802b.tar.gz |
ARM: Update page fault handling for new OOM techniques
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/fault.c | 47 |
1 files changed, 14 insertions, 33 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 1bb3871..501304f 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -223,37 +223,18 @@ good_area: goto out; /* - * If for any reason at all we couldn't handle - * the fault, make sure we exit gracefully rather - * than endlessly redo the fault. + * If for any reason at all we couldn't handle the fault, make + * sure we exit gracefully rather than endlessly redo the fault. */ -survive: fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, (fsr & FSR_WRITE) ? FAULT_FLAG_WRITE : 0); - if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) - goto out_of_memory; - else if (fault & VM_FAULT_SIGBUS) - return fault; - BUG(); - } + if (unlikely(fault & VM_FAULT_ERROR)) + return fault; if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; else tsk->min_flt++; return fault; -out_of_memory: - if (!is_global_init(tsk)) - goto out; - - /* - * If we are out of memory for pid1, sleep for a while and retry - */ - up_read(&mm->mmap_sem); - yield(); - down_read(&mm->mmap_sem); - goto survive; - check_stack: if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) goto good_area; @@ -301,6 +282,16 @@ 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 (fault & VM_FAULT_OOM) { + /* + * We ran out of memory, call the OOM killer, and return to + * userspace (which will retry the fault, or kill us if we + * got oom-killed) + */ + pagefault_out_of_memory(); + return 0; + } + /* * If we are in kernel mode at this point, we * have no context to handle this fault with. @@ -308,16 +299,6 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!user_mode(regs)) goto no_context; - if (fault & VM_FAULT_OOM) { - /* - * We ran out of memory, or some other thing - * happened to us that made us unable to handle - * the page fault gracefully. - */ - printk("VM: killing process %s\n", tsk->comm); - do_group_exit(SIGKILL); - return 0; - } if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to |