diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-20 07:47:40 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-20 07:55:49 -0400 |
commit | b42c6344b091db680fd1ec7a0483e8b6796f802b (patch) | |
tree | 37b25ae64b025dfbf041630e4d4b26b63b0a217f /arch/arm/mm/fault.c | |
parent | c88d6aa71bd2ad7b4da2f281bd64ada65d533d83 (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.c | 47 |
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 | */ |
230 | survive: | ||
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 | ||
245 | out_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 | |||
257 | check_stack: | 238 | check_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 |