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@
This commit is contained in:
parent
0c8713f91e
commit
eca7cac32f
@ -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;
|
||||
/* 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_FRAME;
|
||||
val = 0;
|
||||
}
|
||||
} else {
|
||||
pte = 0;
|
||||
pa = 0;
|
||||
val = 0;
|
||||
}
|
||||
ptep = pmap_pte(pmap, addr);
|
||||
pte = (ptep != NULL) ? *ptep : 0;
|
||||
pmap_pte_release(ptep);
|
||||
if ((pte & PG_V) != 0) {
|
||||
val |= MINCORE_INCORE;
|
||||
val = MINCORE_INCORE;
|
||||
if ((pte & PG_PS) != 0) {
|
||||
val |= MINCORE_SUPER;
|
||||
/* Compute the physical address of the 4KB page. */
|
||||
pa = (pte & PG_PS_FRAME) | (addr & PG_FRAME & PDRMASK);
|
||||
} else
|
||||
pa = pte & PG_FRAME;
|
||||
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) &&
|
||||
|
Loading…
Reference in New Issue
Block a user