ARC: mm: do_page_fault refactor #4: consolidate retry related logic
authorVineet Gupta <vgupta@synopsys.com>
Tue, 14 May 2019 21:35:45 +0000 (14:35 -0700)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 1 Jul 2019 18:02:22 +0000 (11:02 -0700)
stats update code can now elide "retry" check and additional level of
indentation since all retry handling is done ahead of it already

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/mm/fault.c

index 8c7c81ce7f6a873d0d283b41d19c24c0c293af17..4597b4886eddfbb384bab612d46fc37453a4fb7c 100644 (file)
@@ -65,8 +65,8 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
        struct mm_struct *mm = tsk->mm;
        int si_code = SEGV_MAPERR;
        unsigned int write = 0, exec = 0, mask;
-       vm_fault_t fault;
-       unsigned int flags;
+       vm_fault_t fault;                       /* handle_mm_fault() output */
+       unsigned int flags;                     /* handle_mm_fault() input */
 
        /*
         * NOTE! We MUST NOT take any locks for this case. We may
@@ -125,49 +125,51 @@ retry:
                goto bad_area;
        }
 
-       /*
-        * If for any reason at all we couldn't handle the fault,
-        * make sure we exit gracefully rather than endlessly redo
-        * the fault.
-        */
        fault = handle_mm_fault(vma, address, flags);
 
-       if (fatal_signal_pending(current)) {
+       /*
+        * Fault retry nuances
+        */
+       if (unlikely(fault & VM_FAULT_RETRY)) {
 
                /*
-                * if fault retry, mmap_sem already relinquished by core mm
-                * so OK to return to user mode (with signal handled first)
+                * If fault needs to be retried, handle any pending signals
+                * first (by returning to user mode).
+                * mmap_sem already relinquished by core mm for RETRY case
                 */
-               if (fault & VM_FAULT_RETRY) {
+               if (fatal_signal_pending(current)) {
                        if (!user_mode(regs))
                                goto no_context;
                        return;
                }
+               /*
+                * retry state machine
+                */
+               if (flags & FAULT_FLAG_ALLOW_RETRY) {
+                       flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
+                       goto retry;
+               }
        }
 
+       /*
+        * Major/minor page fault accounting
+        * (in case of retry we only land here once)
+        */
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
        if (likely(!(fault & VM_FAULT_ERROR))) {
-               if (flags & FAULT_FLAG_ALLOW_RETRY) {
-                       /* To avoid updating stats twice for retry case */
-                       if (fault & VM_FAULT_MAJOR) {
-                               tsk->maj_flt++;
-                               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
-                                             regs, address);
-                       } else {
-                               tsk->min_flt++;
-                               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
-                                             regs, address);
-                       }
-
-                       if (fault & VM_FAULT_RETRY) {
-                               flags &= ~FAULT_FLAG_ALLOW_RETRY;
-                               flags |= FAULT_FLAG_TRIED;
-                               goto retry;
-                       }
+               if (fault & VM_FAULT_MAJOR) {
+                       tsk->maj_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
+                                     regs, address);
+               } else {
+                       tsk->min_flt++;
+                       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
+                                     regs, address);
                }
 
-               /* Fault Handled Gracefully */
+               /* Normal return path: fault Handled Gracefully */
                up_read(&mm->mmap_sem);
                return;
        }