aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKautuk Consul <consul.kautuk@gmail.com>2012-08-18 22:41:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-19 11:41:19 -0400
commit0bcc426b1defa6b629dfa722537cab38876a3ce4 (patch)
treee545cca77bcafdf9071e0eb7647051e391f4436b /arch
parent28d353d9891c28496e366bebe4e65233f59ad1f6 (diff)
alpha/mm/fault.c: Port OOM changes to do_page_fault
Commit d065bd810b6d ("mm: retry page fault when blocking on disk transfer") and 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 ALPHA. Signed-off-by: Mohd. Faris <mohdfarisq2010@gmail.com> Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Acked-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Michael Cree <mcree@orcon.net.nz> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/mm/fault.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 5eecab1a84ef..0c4132dd3507 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -89,6 +89,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
89 const struct exception_table_entry *fixup; 89 const struct exception_table_entry *fixup;
90 int fault, si_code = SEGV_MAPERR; 90 int fault, si_code = SEGV_MAPERR;
91 siginfo_t info; 91 siginfo_t info;
92 unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
93 (cause > 0 ? FAULT_FLAG_WRITE : 0));
92 94
93 /* As of EV6, a load into $31/$f31 is a prefetch, and never faults 95 /* As of EV6, a load into $31/$f31 is a prefetch, and never faults
94 (or is suppressed by the PALcode). Support that for older CPUs 96 (or is suppressed by the PALcode). Support that for older CPUs
@@ -114,6 +116,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
114 goto vmalloc_fault; 116 goto vmalloc_fault;
115#endif 117#endif
116 118
119retry:
117 down_read(&mm->mmap_sem); 120 down_read(&mm->mmap_sem);
118 vma = find_vma(mm, address); 121 vma = find_vma(mm, address);
119 if (!vma) 122 if (!vma)
@@ -144,8 +147,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
144 /* If for any reason at all we couldn't handle the fault, 147 /* If for any reason at all we couldn't handle the fault,
145 make sure we exit gracefully rather than endlessly redo 148 make sure we exit gracefully rather than endlessly redo
146 the fault. */ 149 the fault. */
147 fault = handle_mm_fault(mm, vma, address, cause > 0 ? FAULT_FLAG_WRITE : 0); 150 fault = handle_mm_fault(mm, vma, address, flags);
148 up_read(&mm->mmap_sem); 151
152 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
153 return;
154
149 if (unlikely(fault & VM_FAULT_ERROR)) { 155 if (unlikely(fault & VM_FAULT_ERROR)) {
150 if (fault & VM_FAULT_OOM) 156 if (fault & VM_FAULT_OOM)
151 goto out_of_memory; 157 goto out_of_memory;
@@ -153,10 +159,26 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
153 goto do_sigbus; 159 goto do_sigbus;
154 BUG(); 160 BUG();
155 } 161 }
156 if (fault & VM_FAULT_MAJOR) 162
157 current->maj_flt++; 163 if (flags & FAULT_FLAG_ALLOW_RETRY) {
158 else 164 if (fault & VM_FAULT_MAJOR)
159 current->min_flt++; 165 current->maj_flt++;
166 else
167 current->min_flt++;
168 if (fault & VM_FAULT_RETRY) {
169 flags &= ~FAULT_FLAG_ALLOW_RETRY;
170
171 /* No need to up_read(&mm->mmap_sem) as we would
172 * have already released it in __lock_page_or_retry
173 * in mm/filemap.c.
174 */
175
176 goto retry;
177 }
178 }
179
180 up_read(&mm->mmap_sem);
181
160 return; 182 return;
161 183
162 /* Something tried to access memory that isn't in our memory map. 184 /* Something tried to access memory that isn't in our memory map.
@@ -186,12 +208,14 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
186 /* We ran out of memory, or some other thing happened to us that 208 /* We ran out of memory, or some other thing happened to us that
187 made us unable to handle the page fault gracefully. */ 209 made us unable to handle the page fault gracefully. */
188 out_of_memory: 210 out_of_memory:
211 up_read(&mm->mmap_sem);
189 if (!user_mode(regs)) 212 if (!user_mode(regs))
190 goto no_context; 213 goto no_context;
191 pagefault_out_of_memory(); 214 pagefault_out_of_memory();
192 return; 215 return;
193 216
194 do_sigbus: 217 do_sigbus:
218 up_read(&mm->mmap_sem);
195 /* Send a sigbus, regardless of whether we were in kernel 219 /* Send a sigbus, regardless of whether we were in kernel
196 or user mode. */ 220 or user mode. */
197 info.si_signo = SIGBUS; 221 info.si_signo = SIGBUS;