svn commit: r216555 - head/sys/i386/i386

Alan Cox alc at FreeBSD.org
Sun Dec 19 07:31:57 UTC 2010


Author: alc
Date: Sun Dec 19 07:31:56 2010
New Revision: 216555
URL: http://svn.freebsd.org/changeset/base/216555

Log:
  Redo some parts of r216333, specifically, the locking changes to
  pmap_extract_and_hold(), and undo the rest.  In particular, I forgot
  that PG_PS and PG_PTE_PAT are the same bit.

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

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Sun Dec 19 06:09:02 2010	(r216554)
+++ head/sys/i386/i386/pmap.c	Sun Dec 19 07:31:56 2010	(r216555)
@@ -1291,21 +1291,23 @@ 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);
-	ptep = pmap_pte(pmap, va);
-	pte = (ptep != NULL) ? *ptep : 0;
-	pmap_pte_release(ptep);
-	PMAP_UNLOCK(pmap);
-	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);
+	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);
+		}
 	}
+	PMAP_UNLOCK(pmap);
 	return (rtval);
 }
 
@@ -1319,30 +1321,40 @@ 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, *ptep;
-	vm_paddr_t locked_pa, pa;
 	vm_page_t m;
+	vm_paddr_t pa;
 
-	locked_pa = 0;
+	pa = 0;
 	m = NULL;
 	PMAP_LOCK(pmap);
 retry:
-	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);
+	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 {
+			ptep = pmap_pte(pmap, va);
+			pte = *ptep;
+			pmap_pte_release(ptep);
+			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);
+			}
+		}
 	}
+	PA_UNLOCK_COND(pa);
 	PMAP_UNLOCK(pmap);
 	return (m);
 }
@@ -4979,30 +4991,39 @@ 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:
-	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;
+	pdep = pmap_pde(pmap, addr);
+	if (*pdep != 0) {
+		if (*pdep & PG_PS) {
+			pte = *pdep;
 			/* Compute the physical address of the 4KB page. */
-			pa = (pte & PG_PS_FRAME) | (addr & PG_FRAME & PDRMASK);
-		} else
+			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_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) &&


More information about the svn-src-all mailing list