Author: alc
Date: Thu Dec  9 20:16:00 2010
New Revision: 216333
URL: http://svn.freebsd.org/changeset/base/216333

Log:
  When r207410 eliminated the acquisition and release of the page queues
  lock from pmap_extract_and_hold(), it didn't take into account that
  pmap_pte_quick() sometimes requires the page queues lock to be held.
  This change reimplements pmap_extract_and_hold() such that it no
  longer uses pmap_pte_quick(), and thus never requires the page queues
  lock.
  
  For consistency, adopt the same idiom as used by the new
  implementation of pmap_extract_and_hold() in pmap_extract() and
  pmap_mincore().  It also happens to make these functions shorter.
  
  Fix a style error in pmap_pte().
  
  Reviewed by:  kib@

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

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c   Thu Dec  9 20:05:29 2010        (r216332)
+++ head/sys/i386/i386/pmap.c   Thu Dec  9 20:16:00 2010        (r216333)
@@ -1213,7 +1213,7 @@ pmap_pte(pmap_t pmap, vm_offset_t va)
                }
                return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
        }
-       return (0);
+       return (NULL);
 }
 
 /*
@@ -1291,21 +1291,19 @@ pmap_pte_quick(pmap_t pmap, vm_offset_t 
 vm_paddr_t 
 pmap_extract(pmap_t pmap, vm_offset_t va)
 {
+       pt_entry_t pte, *ptep;
        vm_paddr_t rtval;
-       pt_entry_t *pte;
-       pd_entry_t pde;
 
        rtval = 0;
        PMAP_LOCK(pmap);
-       pde = pmap->pm_pdir[va >> PDRSHIFT];
-       if (pde != 0) {
-               if ((pde & PG_PS) != 0)
-                       rtval = (pde & PG_PS_FRAME) | (va & PDRMASK);
-               else {
-                       pte = pmap_pte(pmap, va);
-                       rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
-                       pmap_pte_release(pte);
-               }
+       ptep = pmap_pte(pmap, va);
+       pte = (ptep != NULL) ? *ptep : 0;
+       pmap_pte_release(ptep);
+       if ((pte & PG_V) != 0) {
+               if ((pte & PG_PS) != 0)
+                       rtval = (pte & PG_PS_FRAME) | (va & PDRMASK);
+               else
+                       rtval = (pte & PG_FRAME) | (va & PAGE_MASK);
        }
        PMAP_UNLOCK(pmap);
        return (rtval);
@@ -1321,40 +1319,30 @@ pmap_extract(pmap_t pmap, vm_offset_t va
 vm_page_t
 pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
 {
-       pd_entry_t pde;
-       pt_entry_t pte;
+       pt_entry_t pte, *ptep;
+       vm_paddr_t locked_pa, pa;
        vm_page_t m;
-       vm_paddr_t pa;
 
-       pa = 0;
+       locked_pa = 0;
        m = NULL;
        PMAP_LOCK(pmap);
 retry:
-       pde = *pmap_pde(pmap, va);
-       if (pde != 0) {
-               if (pde & PG_PS) {
-                       if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
-                               if (vm_page_pa_tryrelock(pmap, (pde & 
PG_PS_FRAME) |
-                                      (va & PDRMASK), &pa))
-                                       goto retry;
-                               m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
-                                   (va & PDRMASK));
-                               vm_page_hold(m);
-                       }
-               } else {
-                       sched_pin();
-                       pte = *pmap_pte_quick(pmap, va);
-                       if (pte != 0 &&
-                           ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
-                               if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME, 
&pa))
-                                       goto retry;
-                               m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
-                               vm_page_hold(m);
-                       }
-                       sched_unpin();
-               }
+       ptep = pmap_pte(pmap, va);
+       pte = (ptep != NULL) ? *ptep : 0;
+       pmap_pte_release(ptep);
+       if ((pte & PG_V) != 0 &&
+           ((pte & PG_RW) != 0 || (prot & VM_PROT_WRITE) == 0)) {
+               if ((pte & PG_PS) != 0) {
+                       /* Compute the physical address of the 4KB page. */
+                       pa = (pte & PG_PS_FRAME) | (va & PG_FRAME & PDRMASK);
+               } else
+                       pa = pte & PG_FRAME;
+               if (vm_page_pa_tryrelock(pmap, pa, &locked_pa))
+                       goto retry;
+               m = PHYS_TO_VM_PAGE(pa);
+               vm_page_hold(m);
+               PA_UNLOCK(locked_pa);
        }
-       PA_UNLOCK_COND(pa);
        PMAP_UNLOCK(pmap);
        return (m);
 }
@@ -4991,39 +4979,30 @@ pmap_change_attr(vm_offset_t va, vm_size
 int
 pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
 {
-       pd_entry_t *pdep;
        pt_entry_t *ptep, pte;
        vm_paddr_t pa;
        int val;
 
        PMAP_LOCK(pmap);
 retry:
-       pdep = pmap_pde(pmap, addr);
-       if (*pdep != 0) {
-               if (*pdep & PG_PS) {
-                       pte = *pdep;
+       ptep = pmap_pte(pmap, addr);
+       pte = (ptep != NULL) ? *ptep : 0;
+       pmap_pte_release(ptep);
+       if ((pte & PG_V) != 0) {
+               val = MINCORE_INCORE;
+               if ((pte & PG_PS) != 0) {
+                       val |= MINCORE_SUPER;
                        /* Compute the physical address of the 4KB page. */
-                       pa = ((*pdep & PG_PS_FRAME) | (addr & PDRMASK)) &
-                           PG_FRAME;
-                       val = MINCORE_SUPER;
-               } else {
-                       ptep = pmap_pte(pmap, addr);
-                       pte = *ptep;
-                       pmap_pte_release(ptep);
+                       pa = (pte & PG_PS_FRAME) | (addr & PG_FRAME & PDRMASK);
+               } else
                        pa = pte & PG_FRAME;
-                       val = 0;
-               }
-       } else {
-               pte = 0;
-               pa = 0;
-               val = 0;
-       }
-       if ((pte & PG_V) != 0) {
-               val |= MINCORE_INCORE;
                if ((pte & (PG_M | PG_RW)) == (PG_M | PG_RW))
                        val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
                if ((pte & PG_A) != 0)
                        val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
+       } else {
+               val = 0;
+               pa = 0;
        }
        if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
            (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) &&
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to