From 41d8fb122f85c9b2c563198026eae774cbb91da7 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Tue, 20 Mar 2012 14:24:05 +0100 Subject: [PATCH] --- yaml --- r: 307983 b: refs/heads/master c: 4d5914d628360c607dc426ccb1acaf23909ac546 h: refs/heads/master i: 307981: 370cea1e8044fb12697f08beafeecafd27ee6c18 307979: a0fa290712171da4fb1353b0a3eacde8bec82f3b 307975: 7788cc9459c37bf42bfc882ce4aa276866df4051 307967: a4eb8d801bcb15e2437bdb9b8b82f8212ec58d41 v: v3 --- [refs] | 2 +- trunk/arch/cris/mm/fault.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index d867c2730963..ba196b9b2e25 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dfb73a071f0259ba81ceea7b7f312f63dd18c73c +refs/heads/master: 4d5914d628360c607dc426ccb1acaf23909ac546 diff --git a/trunk/arch/cris/mm/fault.c b/trunk/arch/cris/mm/fault.c index b4760d86e1bb..45fd542cf173 100644 --- a/trunk/arch/cris/mm/fault.c +++ b/trunk/arch/cris/mm/fault.c @@ -58,6 +58,8 @@ do_page_fault(unsigned long address, struct pt_regs *regs, struct vm_area_struct * vma; siginfo_t info; int fault; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + ((writeaccess & 1) ? FAULT_FLAG_WRITE : 0); D(printk(KERN_DEBUG "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, if (in_atomic() || !mm) goto no_context; +retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -163,7 +166,11 @@ do_page_fault(unsigned long address, struct pt_regs *regs, * the fault. */ - fault = handle_mm_fault(mm, vma, address, (writeaccess & 1) ? FAULT_FLAG_WRITE : 0); + fault = handle_mm_fault(mm, vma, address, flags); + + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return; + if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -171,10 +178,24 @@ do_page_fault(unsigned long address, struct pt_regs *regs, goto do_sigbus; BUG(); } - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; + + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; + if (fault & VM_FAULT_RETRY) { + flags &= ~FAULT_FLAG_ALLOW_RETRY; + + /* + * No need to up_read(&mm->mmap_sem) as we would + * have already released it in __lock_page_or_retry + * in mm/filemap.c. + */ + + goto retry; + } + } up_read(&mm->mmap_sem); return;