Author: alc
Date: Sat Jul 15 01:49:54 2017
New Revision: 321003
URL: https://svnweb.freebsd.org/changeset/base/321003

Log:
  Extract the innermost loop of pmap_remove() out into its own function,
  pmap_remove_ptes().  (This new function will also be used by an upcoming
  change to pmap_enter() that adds support for psind == 1 mappings.)
  
  Submitted by: Yufeng Zhou <y...@rice.edu> (an earlier version)
  Reviewed by:  kib, markj
  MFC after:    1 week

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

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c Sat Jul 15 00:45:22 2017        (r321002)
+++ head/sys/amd64/amd64/pmap.c Sat Jul 15 01:49:54 2017        (r321003)
@@ -629,6 +629,9 @@ static int pmap_remove_pte(pmap_t pmap, pt_entry_t *pt
 static vm_page_t pmap_remove_pt_page(pmap_t pmap, vm_offset_t va);
 static void pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
     struct spglist *free);
+static bool    pmap_remove_ptes(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
+                   pd_entry_t *pde, struct spglist *free,
+                   struct rwlock **lockp);
 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,
@@ -3736,6 +3739,44 @@ pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry
 }
 
 /*
+ * Removes the specified range of addresses from the page table page.
+ */
+static bool
+pmap_remove_ptes(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
+    pd_entry_t *pde, struct spglist *free, struct rwlock **lockp)
+{
+       pt_entry_t PG_G, *pte;
+       vm_offset_t va;
+       bool anyvalid;
+
+       PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+       PG_G = pmap_global_bit(pmap);
+       anyvalid = false;
+       va = eva;
+       for (pte = pmap_pde_to_pte(pde, sva); sva != eva; pte++,
+           sva += PAGE_SIZE) {
+               if (*pte == 0) {
+                       if (va != eva) {
+                               pmap_invalidate_range(pmap, va, sva);
+                               va = eva;
+                       }
+                       continue;
+               }
+               if ((*pte & PG_G) == 0)
+                       anyvalid = true;
+               else if (va == eva)
+                       va = sva;
+               if (pmap_remove_pte(pmap, pte, sva, *pde, free, lockp)) {
+                       sva += PAGE_SIZE;
+                       break;
+               }
+       }
+       if (va != eva)
+               pmap_invalidate_range(pmap, va, sva);
+       return (anyvalid);
+}
+
+/*
  *     Remove the given range of addresses from the specified map.
  *
  *     It is assumed that the start and end are properly
@@ -3745,11 +3786,11 @@ void
 pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
 {
        struct rwlock *lock;
-       vm_offset_t va, va_next;
+       vm_offset_t va_next;
        pml4_entry_t *pml4e;
        pdp_entry_t *pdpe;
        pd_entry_t ptpaddr, *pde;
-       pt_entry_t *pte, PG_G, PG_V;
+       pt_entry_t PG_G, PG_V;
        struct spglist free;
        int anyvalid;
 
@@ -3852,28 +3893,8 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t 
                if (va_next > eva)
                        va_next = eva;
 
-               va = va_next;
-               for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++,
-                   sva += PAGE_SIZE) {
-                       if (*pte == 0) {
-                               if (va != va_next) {
-                                       pmap_invalidate_range(pmap, va, sva);
-                                       va = va_next;
-                               }
-                               continue;
-                       }
-                       if ((*pte & PG_G) == 0)
-                               anyvalid = 1;
-                       else if (va == va_next)
-                               va = sva;
-                       if (pmap_remove_pte(pmap, pte, sva, ptpaddr, &free,
-                           &lock)) {
-                               sva += PAGE_SIZE;
-                               break;
-                       }
-               }
-               if (va != va_next)
-                       pmap_invalidate_range(pmap, va, sva);
+               if (pmap_remove_ptes(pmap, sva, va_next, pde, &free, &lock))
+                       anyvalid = 1;
        }
        if (lock != NULL)
                rw_wunlock(lock);
_______________________________________________
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