Author: alc
Date: Thu Jun 21 16:37:36 2012
New Revision: 237404
URL: http://svn.freebsd.org/changeset/base/237404

Log:
  Update the PV stats in free_pv_entry() using atomics.  After which, it is
  no longer necessary for free_pv_entry() to be serialized by the pvh global
  lock.
  
  Retire pmap_insert_entry() and pmap_remove_entry().  Once upon a time,
  these functions were called from multiple places within the pmap.  Now,
  each has only one caller.

Modified:
  head/sys/amd64/amd64/pmap.c

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c Thu Jun 21 16:21:31 2012        (r237403)
+++ head/sys/amd64/amd64/pmap.c Thu Jun 21 16:37:36 2012        (r237404)
@@ -275,9 +275,6 @@ static int pmap_remove_pte(pmap_t pmap, 
 static void pmap_remove_pt_page(pmap_t pmap, vm_page_t mpte);
 static void pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
     vm_page_t *free);
-static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
-               vm_offset_t va);
-static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
 static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
     vm_page_t m, struct rwlock **lockp);
 static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
@@ -2207,10 +2204,10 @@ free_pv_entry(pmap_t pmap, pv_entry_t pv
        struct pv_chunk *pc;
        int idx, field, bit;
 
-       rw_assert(&pvh_global_lock, RA_WLOCKED);
+       rw_assert(&pvh_global_lock, RA_LOCKED);
        PMAP_LOCK_ASSERT(pmap, MA_OWNED);
-       PV_STAT(pv_entry_frees++);
-       PV_STAT(pv_entry_spare++);
+       PV_STAT(atomic_add_long(&pv_entry_frees, 1));
+       PV_STAT(atomic_add_int(&pv_entry_spare, 1));
        PV_STAT(atomic_subtract_long(&pv_entry_count, 1));
        pc = pv_to_chunk(pv);
        idx = pv - &pc->pc_pventry[0];
@@ -2372,7 +2369,9 @@ pmap_pv_demote_pde(pmap_t pmap, vm_offse
                KASSERT((m->oflags & VPO_UNMANAGED) == 0,
                    ("pmap_pv_demote_pde: page %p is not managed", m));
                va += PAGE_SIZE;
-               pmap_insert_entry(pmap, va, m);
+               pv = get_pv_entry(pmap, FALSE);
+               pv->pv_va = va;
+               TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
        } while (va < va_last);
 }
 
@@ -2430,36 +2429,6 @@ pmap_pvh_free(struct md_page *pvh, pmap_
        free_pv_entry(pmap, pv);
 }
 
-static void
-pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va)
-{
-       struct md_page *pvh;
-
-       rw_assert(&pvh_global_lock, RA_WLOCKED);
-       pmap_pvh_free(&m->md, pmap, va);
-       if (TAILQ_EMPTY(&m->md.pv_list) && (m->flags & PG_FICTITIOUS) == 0) {
-               pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
-               if (TAILQ_EMPTY(&pvh->pv_list))
-                       vm_page_aflag_clear(m, PGA_WRITEABLE);
-       }
-}
-
-/*
- * Create a pv entry for page at pa for
- * (pmap, va).
- */
-static void
-pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
-{
-       pv_entry_t pv;
-
-       rw_assert(&pvh_global_lock, RA_WLOCKED);
-       PMAP_LOCK_ASSERT(pmap, MA_OWNED);
-       pv = get_pv_entry(pmap, FALSE);
-       pv->pv_va = va;
-       TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
-}
-
 /*
  * Conditionally create a pv entry.
  */
@@ -2711,6 +2680,7 @@ static int
 pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, 
     pd_entry_t ptepde, vm_page_t *free)
 {
+       struct md_page *pvh;
        pt_entry_t oldpte;
        vm_page_t m;
 
@@ -2725,7 +2695,13 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t 
                        vm_page_dirty(m);
                if (oldpte & PG_A)
                        vm_page_aflag_set(m, PGA_REFERENCED);
-               pmap_remove_entry(pmap, m, va);
+               pmap_pvh_free(&m->md, pmap, va);
+               if (TAILQ_EMPTY(&m->md.pv_list) &&
+                   (m->flags & PG_FICTITIOUS) == 0) {
+                       pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
+                       if (TAILQ_EMPTY(&pvh->pv_list))
+                               vm_page_aflag_clear(m, PGA_WRITEABLE);
+               }
        }
        return (pmap_unuse_pt(pmap, va, ptepde, free));
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to