aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/mm/fault.c
diff options
context:
space:
mode:
authorKautuk Consul <consul.kautuk@gmail.com>2012-03-20 09:24:05 -0400
committerJesper Nilsson <jespern@axis.com>2012-04-04 11:50:30 -0400
commit4d5914d628360c607dc426ccb1acaf23909ac546 (patch)
tree711cce67064eabd0d3347fb90ff80c55d59667ed /arch/cris/mm/fault.c
parentdfb73a071f0259ba81ceea7b7f312f63dd18c73c (diff)
cris/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 CRIS. Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch/cris/mm/fault.c')
-rw-r--r--arch/cris/mm/fault.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index b4760d86e1bb..45fd542cf173 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -58,6 +58,8 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
58 struct vm_area_struct * vma; 58 struct vm_area_struct * vma;
59 siginfo_t info; 59 siginfo_t info;
60 int fault; 60 int fault;
61 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
62 ((writeaccess & 1) ? FAULT_FLAG_WRITE : 0);
61 63
62 D(printk(KERN_DEBUG 64 D(printk(KERN_DEBUG
63 "Page fault for %lX on %X at %lX, prot %d write %d\n", 65 "Page fault for %lX on %X at %lX, prot %d write %d\n",
@@ -115,6 +117,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
115 if (in_atomic() || !mm) 117 if (in_atomic() || !mm)
116 goto no_context; 118 goto no_context;
117 119
120retry:
118 down_read(&mm->mmap_sem); 121 down_read(&mm->mmap_sem);
119 vma = find_vma(mm, address); 122 vma = find_vma(mm, address);
120 if (!vma) 123 if (!vma)
@@ -163,7 +166,11 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
163 * the fault. 166 * the fault.
164 */ 167 */
165 168
166 fault = handle_mm_fault(mm, vma, address, (writeaccess & 1) ? FAULT_FLAG_WRITE : 0); 169 fault = handle_mm_fault(mm, vma, address, flags);
170
171 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
172 return;
173
167 if (unlikely(fault & VM_FAULT_ERROR)) { 174 if (unlikely(fault & VM_FAULT_ERROR)) {
168 if (fault & VM_FAULT_OOM) 175 if (fault & VM_FAULT_OOM)
169 goto out_of_memory; 176 goto out_of_memory;
@@ -171,10 +178,24 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
171 goto do_sigbus; 178 goto do_sigbus;
172 BUG(); 179 BUG();
173 } 180 }
174 if (fault & VM_FAULT_MAJOR) 181
175 tsk->maj_flt++; 182 if (flags & FAULT_FLAG_ALLOW_RETRY) {
176 else 183 if (fault & VM_FAULT_MAJOR)
177 tsk->min_flt++; 184 tsk->maj_flt++;
185 else
186 tsk->min_flt++;
187 if (fault & VM_FAULT_RETRY) {
188 flags &= ~FAULT_FLAG_ALLOW_RETRY;
189
190 /*
191 * No need to up_read(&mm->mmap_sem) as we would
192 * have already released it in __lock_page_or_retry
193 * in mm/filemap.c.
194 */
195
196 goto retry;
197 }
198 }
178 199
179 up_read(&mm->mmap_sem); 200 up_read(&mm->mmap_sem);
180 return; 201 return;