Author: alc
Date: Mon Jul  2 05:57:44 2012
New Revision: 237952
URL: http://svn.freebsd.org/changeset/base/237952

Log:
  MFC r235912
    There is no need for pmap_protect() to acquire the page queues lock
    unless it is going to access the pv lists or PMAP1/PADDR1.

Modified:
  stable/9/sys/i386/i386/pmap.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/i386/i386/pmap.c
==============================================================================
--- stable/9/sys/i386/i386/pmap.c       Mon Jul  2 05:57:01 2012        
(r237951)
+++ stable/9/sys/i386/i386/pmap.c       Mon Jul  2 05:57:44 2012        
(r237952)
@@ -3125,7 +3125,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
        vm_offset_t pdnxt;
        pd_entry_t ptpaddr;
        pt_entry_t *pte;
-       int anychanged;
+       boolean_t anychanged, pv_lists_locked;
 
        if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
                pmap_remove(pmap, sva, eva);
@@ -3141,10 +3141,16 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
                return;
 #endif
 
-       anychanged = 0;
+       if (pmap_is_current(pmap))
+               pv_lists_locked = FALSE;
+       else {
+               pv_lists_locked = TRUE;
+resume:
+               vm_page_lock_queues();
+               sched_pin();
+       }
+       anychanged = FALSE;
 
-       vm_page_lock_queues();
-       sched_pin();
        PMAP_LOCK(pmap);
        for (; sva < eva; sva = pdnxt) {
                pt_entry_t obits, pbits;
@@ -3179,12 +3185,27 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
                                 */
                                if (pmap_protect_pde(pmap,
                                    &pmap->pm_pdir[pdirindex], sva, prot))
-                                       anychanged = 1;
-                               continue;
-                       } else if (!pmap_demote_pde(pmap,
-                           &pmap->pm_pdir[pdirindex], sva)) {
-                               /* The large page mapping was destroyed. */
+                                       anychanged = TRUE;
                                continue;
+                       } else {
+                               if (!pv_lists_locked) {
+                                       pv_lists_locked = TRUE;
+                                       if (!mtx_trylock(&vm_page_queue_mtx)) {
+                                               if (anychanged)
+                                                       pmap_invalidate_all(
+                                                           pmap);
+                                               PMAP_UNLOCK(pmap);
+                                               goto resume;
+                                       }
+                               }
+                               if (!pmap_demote_pde(pmap,
+                                   &pmap->pm_pdir[pdirindex], sva)) {
+                                       /*
+                                        * The large page mapping was
+                                        * destroyed.
+                                        */
+                                       continue;
+                               }
                        }
                }
 
@@ -3230,14 +3251,16 @@ retry:
                                if (obits & PG_G)
                                        pmap_invalidate_page(pmap, sva);
                                else
-                                       anychanged = 1;
+                                       anychanged = TRUE;
                        }
                }
        }
-       sched_unpin();
        if (anychanged)
                pmap_invalidate_all(pmap);
-       vm_page_unlock_queues();
+       if (pv_lists_locked) {
+               sched_unpin();
+               vm_page_unlock_queues();
+       }
        PMAP_UNLOCK(pmap);
 }
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to