summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2012-10-06 19:05:50 +0000
committeralc <alc@FreeBSD.org>2012-10-06 19:05:50 +0000
commit78ade40ed1d3591a0bf9f5a1bb057c1f4084135d (patch)
tree48d1854453004dce8d54de7aa2edd9b551ef95f9
parent9f91838f634b0f54d147edca722735d285752e3f (diff)
downloadFreeBSD-src-78ade40ed1d3591a0bf9f5a1bb057c1f4084135d.zip
FreeBSD-src-78ade40ed1d3591a0bf9f5a1bb057c1f4084135d.tar.gz
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.
-rw-r--r--sys/mips/mips/pmap.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index e04857b..4c5ea74 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -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);
OpenPOWER on IntegriCloud