From d3e0c885770951c7285ea79d11b1cdfc96e6600f Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Tue, 20 Mar 2012 09:21:40 -0400 Subject: [PATCH] --- yaml --- r: 308490 b: refs/heads/master c: f397c077e114df07bd2b94a16681a04be8d59dff h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/microblaze/mm/fault.c | 33 +++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index a3ffe9ff6d8a..0174f4335b09 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 59516b07b4ffa7e607a5787674ea3c405f1b390c +refs/heads/master: f397c077e114df07bd2b94a16681a04be8d59dff diff --git a/trunk/arch/microblaze/mm/fault.c b/trunk/arch/microblaze/mm/fault.c index c38a265846de..eb365d6795fa 100644 --- a/trunk/arch/microblaze/mm/fault.c +++ b/trunk/arch/microblaze/mm/fault.c @@ -92,6 +92,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, int code = SEGV_MAPERR; int is_write = error_code & ESR_S; int fault; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + (is_write ? FAULT_FLAG_WRITE : 0); regs->ear = address; regs->esr = error_code; @@ -138,6 +140,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, if (kernel_mode(regs) && !search_exception_tables(regs->pc)) goto bad_area_nosemaphore; +retry: down_read(&mm->mmap_sem); } @@ -210,7 +213,11 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, * make sure we exit gracefully rather than endlessly redo * the fault. */ - fault = handle_mm_fault(mm, vma, address, is_write ? 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; @@ -218,11 +225,27 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, goto do_sigbus; BUG(); } - if (unlikely(fault & VM_FAULT_MAJOR)) - current->maj_flt++; - else - current->min_flt++; + + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (unlikely(fault & VM_FAULT_MAJOR)) + current->maj_flt++; + else + current->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); + /* * keep track of tlb+htab misses that are good addrs but * just need pte's created via handle_mm_fault()