Subject: mm: optimise handle_speculative_fault() From: Peter Zijlstra Date: Tue Jan 05 09:43:04 CET 2010 We don't need to hold the ptl to read the pte entry, and since we already do the double seqlock vma validation, put the entry read in between. Signed-off-by: Peter Zijlstra LKML-Reference: --- mm/memory.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c +++ linux-2.6/mm/memory.c @@ -3106,7 +3106,6 @@ int handle_speculative_fault(struct mm_s pud_t *pud; pmd_t *pmd; pte_t *pte, entry; - spinlock_t *ptl; struct vm_area_struct *vma; unsigned int seq; int dead, ret = VM_FAULT_RETRY; @@ -3117,7 +3116,6 @@ int handle_speculative_fault(struct mm_s count_vm_event(PGFAULT); rcu_read_lock(); -again: pin_page_tables(); pgd = pgd_offset(mm, address); @@ -3135,13 +3133,7 @@ again: if (pmd_huge(*pmd)) goto out; - ptl = pte_lockptr(mm, pmd); pte = pte_offset_map(pmd, address); - if (!spin_trylock(ptl)) { - pte_unmap(pte); - unpin_page_tables(); - goto again; - } vma = find_vma(mm, address); @@ -3161,12 +3153,12 @@ again: if (!(vma->vm_end > address && vma->vm_start <= address)) goto out_unmap; + entry = *pte; + if (read_seqcount_retry(&vma->vm_sequence, seq)) goto out_unmap; - entry = *pte; - - pte_unmap_unlock(pte, ptl); + pte_unmap(pte); unpin_page_tables(); ret = handle_pte_fault(mm, vma, address, entry, pmd, flags, seq); @@ -3176,7 +3168,7 @@ out_unlock: return ret; out_unmap: - pte_unmap_unlock(pte, ptl); + pte_unmap(pte); out: unpin_page_tables(); goto out_unlock;