aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKautuk Consul <consul.kautuk@gmail.com>2012-03-20 09:26:53 -0400
committerHelge Deller <deller@gmx.de>2013-02-20 16:51:31 -0500
commit38057477b98712bd9c735bf9d26b83c25d9d3279 (patch)
tree681dc06615614aa94605404a58e31620d856e3ca
parent45b6eff2a60c8bec1254412dfdb36acb0afe04a2 (diff)
parisc/mm/fault.c: Port OOM changes to do_page_fault
Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits 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 parisc. Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/mm/fault.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 18162ce4261e..f247a3480e8e 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -175,10 +175,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
175 struct mm_struct *mm = tsk->mm; 175 struct mm_struct *mm = tsk->mm;
176 unsigned long acc_type; 176 unsigned long acc_type;
177 int fault; 177 int fault;
178 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
178 179
179 if (in_atomic() || !mm) 180 if (in_atomic() || !mm)
180 goto no_context; 181 goto no_context;
181 182
183retry:
182 down_read(&mm->mmap_sem); 184 down_read(&mm->mmap_sem);
183 vma = find_vma_prev(mm, address, &prev_vma); 185 vma = find_vma_prev(mm, address, &prev_vma);
184 if (!vma || address < vma->vm_start) 186 if (!vma || address < vma->vm_start)
@@ -201,7 +203,12 @@ good_area:
201 * fault. 203 * fault.
202 */ 204 */
203 205
204 fault = handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) ? FAULT_FLAG_WRITE : 0); 206 fault = handle_mm_fault(mm, vma, address,
207 flags | ((acc_type & VM_WRITE) ? FAULT_FLAG_WRITE : 0));
208
209 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
210 return;
211
205 if (unlikely(fault & VM_FAULT_ERROR)) { 212 if (unlikely(fault & VM_FAULT_ERROR)) {
206 /* 213 /*
207 * We hit a shared mapping outside of the file, or some 214 * We hit a shared mapping outside of the file, or some
@@ -214,10 +221,23 @@ good_area:
214 goto bad_area; 221 goto bad_area;
215 BUG(); 222 BUG();
216 } 223 }
217 if (fault & VM_FAULT_MAJOR) 224 if (flags & FAULT_FLAG_ALLOW_RETRY) {
218 current->maj_flt++; 225 if (fault & VM_FAULT_MAJOR)
219 else 226 current->maj_flt++;
220 current->min_flt++; 227 else
228 current->min_flt++;
229 if (fault & VM_FAULT_RETRY) {
230 flags &= ~FAULT_FLAG_ALLOW_RETRY;
231
232 /*
233 * No need to up_read(&mm->mmap_sem) as we would
234 * have already released it in __lock_page_or_retry
235 * in mm/filemap.c.
236 */
237
238 goto retry;
239 }
240 }
221 up_read(&mm->mmap_sem); 241 up_read(&mm->mmap_sem);
222 return; 242 return;
223 243