aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2010-12-09 20:16:00 +0000
committerAlan Cox <alc@FreeBSD.org>2010-12-09 20:16:00 +0000
commitd1cf854b5df45ec607652c7fb1ac1e51a3218610 (patch)
tree9720ae95e7f5c2244f283d29e31966b0541bd764
parentb4a8d95279d9568e67ff32c963bf8c1c368628ad (diff)
downloadsrc-d1cf854b5df45ec607652c7fb1ac1e51a3218610.tar.gz
src-d1cf854b5df45ec607652c7fb1ac1e51a3218610.zip
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@
Notes
Notes: svn path=/head/; revision=216333
-rw-r--r--sys/i386/i386/pmap.c101
1 files changed, 40 insertions, 61 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 7efa29c5537a..b7d36489d625 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -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 va)
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_t size, int mode)
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) &&