Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1715aea1 authored by Laurent Dufour's avatar Laurent Dufour Committed by Vinayak Menon
Browse files

mm: introduce pte_spinlock for FAULT_FLAG_SPECULATIVE



When handling page fault without holding the mmap_sem the fetch of the
pte lock pointer and the locking will have to be done while ensuring
that the VMA is not touched in our back.

So move the fetch and locking operations in a dedicated function.

Change-Id: If93ab95b1d22b7195e1c15b57315021f6be7c394
Signed-off-by: default avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Patch-mainline: linux-mm @ Tue, 17 Apr 2018 16:33:11
[vinmenon@codeaurora.org: 4.9 port merge conflicts]
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent c3e62fff
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1961,6 +1961,14 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
}
EXPORT_SYMBOL_GPL(apply_to_page_range);

static inline bool pte_spinlock(struct mm_struct *mm,
			struct fault_env *fe)
{
	fe->ptl = pte_lockptr(mm, fe->pmd);
	spin_lock(fe->ptl);
	return true;
}

static inline bool pte_map_lock(struct mm_struct *mm,
			struct fault_env *fe)
{
@@ -3373,8 +3381,8 @@ static int do_numa_page(struct fault_env *fe, pte_t pte)
	* page table entry is not accessible, so there would be no
	* concurrent hardware modifications to the PTE.
	*/
	fe->ptl = pte_lockptr(vma->vm_mm, fe->pmd);
	spin_lock(fe->ptl);
	if (!pte_spinlock(vma->vm_mm, fe))
		return VM_FAULT_RETRY;
	if (unlikely(!pte_same(*fe->pte, pte))) {
		pte_unmap_unlock(fe->pte, fe->ptl);
		goto out;
@@ -3542,8 +3550,8 @@ static int handle_pte_fault(struct fault_env *fe)
	if (pte_protnone(entry) && vma_is_accessible(fe->vma))
		return do_numa_page(fe, entry);

	fe->ptl = pte_lockptr(fe->vma->vm_mm, fe->pmd);
	spin_lock(fe->ptl);
	if (!pte_spinlock(fe->vma->vm_mm, fe))
		return VM_FAULT_RETRY;
	if (unlikely(!pte_same(*fe->pte, entry)))
		goto unlock;
	if (fe->flags & FAULT_FLAG_WRITE) {