aboutsummaryrefslogtreecommitdiffstats
path: root/arch/openrisc/mm
diff options
context:
space:
mode:
authorKautuk Consul <consul.kautuk@gmail.com>2012-03-31 08:00:51 -0400
committerJonas Bonn <jonas@southpole.se>2012-05-08 05:43:20 -0400
commit4971f2bdb746e6cc8423ea60f99694884f6052c5 (patch)
tree9ad37df4ecc0d57b478f3f4f22b775bd4f848da8 /arch/openrisc/mm
parentad188f955a79f5501b0cd5bde2b0621b3c78044a (diff)
openrisc/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 openrisc. Signed-off-by: Mohd. Faris <mohdfarisq2010@gmail.com> Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Signed-off-by: Jonas Bonn <jonas@southpole.se>
Diffstat (limited to 'arch/openrisc/mm')
-rw-r--r--arch/openrisc/mm/fault.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index a5dce82f864b..40f850e9766c 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -54,6 +54,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
54 struct vm_area_struct *vma; 54 struct vm_area_struct *vma;
55 siginfo_t info; 55 siginfo_t info;
56 int fault; 56 int fault;
57 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
57 58
58 tsk = current; 59 tsk = current;
59 60
@@ -105,6 +106,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
105 if (in_interrupt() || !mm) 106 if (in_interrupt() || !mm)
106 goto no_context; 107 goto no_context;
107 108
109retry:
108 down_read(&mm->mmap_sem); 110 down_read(&mm->mmap_sem);
109 vma = find_vma(mm, address); 111 vma = find_vma(mm, address);
110 112
@@ -143,6 +145,7 @@ good_area:
143 if (write_acc) { 145 if (write_acc) {
144 if (!(vma->vm_flags & VM_WRITE)) 146 if (!(vma->vm_flags & VM_WRITE))
145 goto bad_area; 147 goto bad_area;
148 flags |= FAULT_FLAG_WRITE;
146 } else { 149 } else {
147 /* not present */ 150 /* not present */
148 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 151 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
@@ -159,7 +162,11 @@ good_area:
159 * the fault. 162 * the fault.
160 */ 163 */
161 164
162 fault = handle_mm_fault(mm, vma, address, write_acc); 165 fault = handle_mm_fault(mm, vma, address, flags);
166
167 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
168 return;
169
163 if (unlikely(fault & VM_FAULT_ERROR)) { 170 if (unlikely(fault & VM_FAULT_ERROR)) {
164 if (fault & VM_FAULT_OOM) 171 if (fault & VM_FAULT_OOM)
165 goto out_of_memory; 172 goto out_of_memory;
@@ -167,11 +174,24 @@ good_area:
167 goto do_sigbus; 174 goto do_sigbus;
168 BUG(); 175 BUG();
169 } 176 }
170 /*RGD modeled on Cris */ 177
171 if (fault & VM_FAULT_MAJOR) 178 if (flags & FAULT_FLAG_ALLOW_RETRY) {
172 tsk->maj_flt++; 179 /*RGD modeled on Cris */
173 else 180 if (fault & VM_FAULT_MAJOR)
174 tsk->min_flt++; 181 tsk->maj_flt++;
182 else
183 tsk->min_flt++;
184 if (fault & VM_FAULT_RETRY) {
185 flags &= ~FAULT_FLAG_ALLOW_RETRY;
186
187 /* No need to up_read(&mm->mmap_sem) as we would
188 * have already released it in __lock_page_or_retry
189 * in mm/filemap.c.
190 */
191
192 goto retry;
193 }
194 }
175 195
176 up_read(&mm->mmap_sem); 196 up_read(&mm->mmap_sem);
177 return; 197 return;