Author: jhibbits
Date: Wed May  8 16:05:18 2019
New Revision: 347350
URL: https://svnweb.freebsd.org/changeset/base/347350

Log:
  powerpc/booke: Do as much work outside of TLB locks as possible
  
  Reduce the surface area of the TLB locks.  Unfortunately the same trick for
  serializing the tlbie instruction on OEA64 cannot be used here to reduce the
  scope of the tlbivax mutex to the tlbsync only, as the mutex also serializes
  the TLB miss lock as a side effect, so contention on this lock may not be
  reducible any further.

Modified:
  head/sys/powerpc/booke/pmap.c

Modified: head/sys/powerpc/booke/pmap.c
==============================================================================
--- head/sys/powerpc/booke/pmap.c       Wed May  8 16:04:33 2019        
(r347349)
+++ head/sys/powerpc/booke/pmap.c       Wed May  8 16:05:18 2019        
(r347350)
@@ -1382,7 +1382,7 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
        unsigned int    pp2d_idx = PP2D_IDX(va);
        unsigned int    pdir_idx = PDIR_IDX(va);
        unsigned int    ptbl_idx = PTBL_IDX(va);
-       pte_t          *ptbl, *pte;
+       pte_t          *ptbl, *pte, pte_tmp;
        pte_t         **pdir;
 
        /* Get the page directory pointer. */
@@ -1400,12 +1400,13 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
                        KASSERT(nosleep, ("nosleep and NULL ptbl"));
                        return (ENOMEM);
                }
+               pte = &ptbl[ptbl_idx];
        } else {
                /*
                 * Check if there is valid mapping for requested va, if there
                 * is, remove it.
                 */
-               pte = &pdir[pdir_idx][ptbl_idx];
+               pte = &ptbl[ptbl_idx];
                if (PTE_ISVALID(pte)) {
                        pte_remove(mmu, pmap, va, PTBL_HOLD);
                } else {
@@ -1437,14 +1438,16 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
                pv_insert(pmap, va, m);
        }
 
+       pmap->pm_stats.resident_count++;
+
+       pte_tmp = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m));
+       pte_tmp |= (PTE_VALID | flags);
+
        mtx_lock_spin(&tlbivax_mutex);
        tlb_miss_lock();
 
        tlb0_flush_entry(va);
-       pmap->pm_stats.resident_count++;
-       pte = &pdir[pdir_idx][ptbl_idx];
-       *pte = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m));
-       *pte |= (PTE_VALID | flags);
+       *pte = pte_tmp;
 
        tlb_miss_unlock();
        mtx_unlock_spin(&tlbivax_mutex);
@@ -1583,7 +1586,7 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
 {
        unsigned int pdir_idx = PDIR_IDX(va);
        unsigned int ptbl_idx = PTBL_IDX(va);
-       pte_t *ptbl, *pte;
+       pte_t *ptbl, *pte, pte_tmp;
 
        CTR4(KTR_PMAP, "%s: su = %d pmap = %p va = %p", __func__,
            pmap == kernel_pmap, pmap, va);
@@ -1598,6 +1601,8 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
                        KASSERT(nosleep, ("nosleep and NULL ptbl"));
                        return (ENOMEM);
                }
+               pmap->pm_pdir[pdir_idx] = ptbl;
+               pte = &ptbl[ptbl_idx];
        } else {
                /*
                 * Check if there is valid mapping for requested
@@ -1629,20 +1634,14 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offs
 
        pmap->pm_stats.resident_count++;
        
+       pte_tmp = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m));
+       pte_tmp |= (PTE_VALID | flags | PTE_PS_4KB); /* 4KB pages only */
+
        mtx_lock_spin(&tlbivax_mutex);
        tlb_miss_lock();
 
        tlb0_flush_entry(va);
-       if (pmap->pm_pdir[pdir_idx] == NULL) {
-               /*
-                * If we just allocated a new page table, hook it in
-                * the pdir.
-                */
-               pmap->pm_pdir[pdir_idx] = ptbl;
-       }
-       pte = &(pmap->pm_pdir[pdir_idx][ptbl_idx]);
-       *pte = PTE_RPN_FROM_PA(VM_PAGE_TO_PHYS(m));
-       *pte |= (PTE_VALID | flags | PTE_PS_4KB); /* 4KB pages only */
+       *pte = pte_tmp;
 
        tlb_miss_unlock();
        mtx_unlock_spin(&tlbivax_mutex);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to