Commit 14c02e41 authored by Laurent Dufour's avatar Laurent Dufour Committed by Michael Ellerman
Browse files

powerpc/mm: Handle VM_FAULT_RETRY earlier



In do_page_fault() if handle_mm_fault() returns VM_FAULT_RETRY, retry
the page fault handling before anything else.

This would simplify the handling of the mmap_sem lock in this part of
the code.

Reviewed-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent c2294e0f
Loading
Loading
Loading
Loading
+38 −29
Original line number Diff line number Diff line
@@ -458,6 +458,26 @@ good_area:
	 * the fault.
	 */
	fault = handle_mm_fault(vma, address, flags);

	/*
	 * Handle the retry right now, the mmap_sem has been released in that
	 * case.
	 */
	if (unlikely(fault & VM_FAULT_RETRY)) {
		/* We retry only once */
		if (flags & FAULT_FLAG_ALLOW_RETRY) {
			/*
			 * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
			 * of starvation.
			 */
			flags &= ~FAULT_FLAG_ALLOW_RETRY;
			flags |= FAULT_FLAG_TRIED;
			if (!fatal_signal_pending(current))
				goto retry;
		}
		/* We will enter mm_fault_error() below */
	}

	if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
		if (fault & VM_FAULT_SIGSEGV)
			goto bad_area;
@@ -469,11 +489,8 @@ good_area:
	}

	/*
	 * Major/minor page fault accounting is only done on the
	 * initial attempt. If we go through a retry, it is extremely
	 * likely that the page will be found in page cache at that point.
	 * Major/minor page fault accounting.
	 */
	if (flags & FAULT_FLAG_ALLOW_RETRY) {
	if (fault & VM_FAULT_MAJOR) {
		current->maj_flt++;
		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
@@ -494,14 +511,6 @@ good_area:
		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
			      regs, address);
	}
		if (fault & VM_FAULT_RETRY) {
			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
			 * of starvation. */
			flags &= ~FAULT_FLAG_ALLOW_RETRY;
			flags |= FAULT_FLAG_TRIED;
			goto retry;
		}
	}

	up_read(&mm->mmap_sem);
	goto bail;