aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorKautuk Consul <consul.kautuk@gmail.com>2012-05-31 19:26:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 20:49:26 -0400
commit1cefe28f95da307287a05a6a0c10213f01055e2a (patch)
tree6810a5c8f413f67d359da6243ee75c60c704d16c /arch/um/kernel
parent4f1c28d241d0882f25112d494885cd6084db225b (diff)
um/kernel/trap.c: port OOM changes to handle_page_fault()
Commit d065bd810b6d ("mm: retry page fault when blocking on disk transfer") and commit 37b23e0525d3 ("x86,mm: make pagefault killable") introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to um. Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Cc: Jeff Dike <jdike@addtoit.com> Cc: Richard Weinberger <richard@nod.at> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/trap.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index dafc94715950..3be60765c0e2 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -30,6 +30,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
30 pmd_t *pmd; 30 pmd_t *pmd;
31 pte_t *pte; 31 pte_t *pte;
32 int err = -EFAULT; 32 int err = -EFAULT;
33 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
34 (is_write ? FAULT_FLAG_WRITE : 0);
33 35
34 *code_out = SEGV_MAPERR; 36 *code_out = SEGV_MAPERR;
35 37
@@ -40,6 +42,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
40 if (in_atomic()) 42 if (in_atomic())
41 goto out_nosemaphore; 43 goto out_nosemaphore;
42 44
45retry:
43 down_read(&mm->mmap_sem); 46 down_read(&mm->mmap_sem);
44 vma = find_vma(mm, address); 47 vma = find_vma(mm, address);
45 if (!vma) 48 if (!vma)
@@ -65,7 +68,11 @@ good_area:
65 do { 68 do {
66 int fault; 69 int fault;
67 70
68 fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); 71 fault = handle_mm_fault(mm, vma, address, flags);
72
73 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
74 goto out_nosemaphore;
75
69 if (unlikely(fault & VM_FAULT_ERROR)) { 76 if (unlikely(fault & VM_FAULT_ERROR)) {
70 if (fault & VM_FAULT_OOM) { 77 if (fault & VM_FAULT_OOM) {
71 goto out_of_memory; 78 goto out_of_memory;
@@ -75,10 +82,17 @@ good_area:
75 } 82 }
76 BUG(); 83 BUG();
77 } 84 }
78 if (fault & VM_FAULT_MAJOR) 85 if (flags & FAULT_FLAG_ALLOW_RETRY) {
79 current->maj_flt++; 86 if (fault & VM_FAULT_MAJOR)
80 else 87 current->maj_flt++;
81 current->min_flt++; 88 else
89 current->min_flt++;
90 if (fault & VM_FAULT_RETRY) {
91 flags &= ~FAULT_FLAG_ALLOW_RETRY;
92
93 goto retry;
94 }
95 }
82 96
83 pgd = pgd_offset(mm, address); 97 pgd = pgd_offset(mm, address);
84 pud = pud_offset(pgd, address); 98 pud = pud_offset(pgd, address);