aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/fault.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-09-20 07:47:40 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-09-20 07:55:49 -0400
commitb42c6344b091db680fd1ec7a0483e8b6796f802b (patch)
tree37b25ae64b025dfbf041630e4d4b26b63b0a217f /arch/arm/mm/fault.c
parentc88d6aa71bd2ad7b4da2f281bd64ada65d533d83 (diff)
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/fault.c')
-rw-r--r--arch/arm/mm/fault.c47
1 files changed, 14 insertions, 33 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 1bb38712c86b..501304f7e30c 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -223,37 +223,18 @@ good_area:
223 goto out; 223 goto out;
224 224
225 /* 225 /*
226 * If for any reason at all we couldn't handle 226 * If for any reason at all we couldn't handle the fault, make
227 * the fault, make sure we exit gracefully rather 227 * sure we exit gracefully rather than endlessly redo the fault.
228 * than endlessly redo the fault.
229 */ 228 */
230survive:
231 fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, (fsr & FSR_WRITE) ? FAULT_FLAG_WRITE : 0); 229 fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, (fsr & FSR_WRITE) ? FAULT_FLAG_WRITE : 0);
232 if (unlikely(fault & VM_FAULT_ERROR)) { 230 if (unlikely(fault & VM_FAULT_ERROR))
233 if (fault & VM_FAULT_OOM) 231 return fault;
234 goto out_of_memory;
235 else if (fault & VM_FAULT_SIGBUS)
236 return fault;
237 BUG();
238 }
239 if (fault & VM_FAULT_MAJOR) 232 if (fault & VM_FAULT_MAJOR)
240 tsk->maj_flt++; 233 tsk->maj_flt++;
241 else 234 else
242 tsk->min_flt++; 235 tsk->min_flt++;
243 return fault; 236 return fault;
244 237
245out_of_memory:
246 if (!is_global_init(tsk))
247 goto out;
248
249 /*
250 * If we are out of memory for pid1, sleep for a while and retry
251 */
252 up_read(&mm->mmap_sem);
253 yield();
254 down_read(&mm->mmap_sem);
255 goto survive;
256
257check_stack: 238check_stack:
258 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) 239 if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
259 goto good_area; 240 goto good_area;
@@ -301,6 +282,16 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
301 if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) 282 if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
302 return 0; 283 return 0;
303 284
285 if (fault & VM_FAULT_OOM) {
286 /*
287 * We ran out of memory, call the OOM killer, and return to
288 * userspace (which will retry the fault, or kill us if we
289 * got oom-killed)
290 */
291 pagefault_out_of_memory();
292 return 0;
293 }
294
304 /* 295 /*
305 * If we are in kernel mode at this point, we 296 * If we are in kernel mode at this point, we
306 * have no context to handle this fault with. 297 * 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)
308 if (!user_mode(regs)) 299 if (!user_mode(regs))
309 goto no_context; 300 goto no_context;
310 301
311 if (fault & VM_FAULT_OOM) {
312 /*
313 * We ran out of memory, or some other thing
314 * happened to us that made us unable to handle
315 * the page fault gracefully.
316 */
317 printk("VM: killing process %s\n", tsk->comm);
318 do_group_exit(SIGKILL);
319 return 0;
320 }
321 if (fault & VM_FAULT_SIGBUS) { 302 if (fault & VM_FAULT_SIGBUS) {
322 /* 303 /*
323 * We had some memory, but were unable to 304 * We had some memory, but were unable to