Correct two pessimizations in pmap_extract_and_hold(). Test the PTE for

having PTE_RO set instead of PTE_D.  This avoids some unnecessary failures
by pmap_extract_and_hold() that will have to be handled by a call to
vm_fault_hold().  Testing the PTE for both being non-zero and having PTE_V
set is redundant.  The latter suffices.
This commit is contained in:
Alan Cox 2012-10-06 19:05:50 +00:00
parent 5847daf4c2
commit 948aea4031
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241276

View File

@ -791,24 +791,25 @@ 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)
{
pt_entry_t *ptep;
pt_entry_t pte;
pt_entry_t pte, *ptep;
vm_paddr_t pa, pte_pa;
vm_page_t m;
vm_paddr_t pa;
m = NULL;
pa = 0;
PMAP_LOCK(pmap);
retry:
ptep = pmap_pte(pmap, va);
if ((ptep != NULL) && ((pte = *ptep) != 0) &&
pte_test(&pte, PTE_V) &&
(pte_test(&pte, PTE_D) || (prot & VM_PROT_WRITE) == 0)) {
if (vm_page_pa_tryrelock(pmap, TLBLO_PTE_TO_PA(pte), &pa))
goto retry;
m = PHYS_TO_VM_PAGE(TLBLO_PTE_TO_PA(pte));
vm_page_hold(m);
if (ptep != NULL) {
pte = *ptep;
if (pte_test(&pte, PTE_V) && (!pte_test(&pte, PTE_RO) ||
(prot & VM_PROT_WRITE) == 0)) {
pte_pa = TLBLO_PTE_TO_PA(pte);
if (vm_page_pa_tryrelock(pmap, pte_pa, &pa))
goto retry;
m = PHYS_TO_VM_PAGE(pte_pa);
vm_page_hold(m);
}
}
PA_UNLOCK_COND(pa);
PMAP_UNLOCK(pmap);