diff options
author | dfr <dfr@FreeBSD.org> | 2001-11-30 10:07:54 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2001-11-30 10:07:54 +0000 |
commit | dedc5f403f182feca669fb72974226b658f334af (patch) | |
tree | 8476f4dd8b45f627d3c80376a0e53581b1415ce3 /sys | |
parent | b75f309317d943a57fb212f17a1ddef6c8fd9291 (diff) | |
download | FreeBSD-src-dedc5f403f182feca669fb72974226b658f334af.zip FreeBSD-src-dedc5f403f182feca669fb72974226b658f334af.tar.gz |
* Don't use critical_enter/critical_exit when accessing the VHPT - its
pointless and would be inadequate for SMP systems. We will rely on the
VM system's locks to serialise this for now.
* Change pmap_remove() so that if the range being removed is larger than
the number of pages mapped by the pmap, we iterate over the currently
mapped pages instead of over the virtual address range. This should
make a difference when removing large virtual address ranges from an
address space.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ia64/ia64/pmap.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 6bf1650..34b129d 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -977,7 +977,6 @@ static void pmap_enter_vhpt(struct ia64_lpte *pte, vm_offset_t va) { struct ia64_lpte *vhpte; - critical_t c = critical_enter(); pmap_vhpt_inserts++; pmap_vhpt_resident++; @@ -994,8 +993,6 @@ pmap_enter_vhpt(struct ia64_lpte *pte, vm_offset_t va) pmap_install_pte(vhpte, pte); else ia64_mf(); - - critical_exit(c); } /* @@ -1005,15 +1002,12 @@ static void pmap_update_vhpt(struct ia64_lpte *pte, vm_offset_t va) { struct ia64_lpte *vhpte; - critical_t c = critical_enter(); vhpte = (struct ia64_lpte *) ia64_thash(va); if ((!vhpte->pte_p || vhpte->pte_tag == pte->pte_tag) && pte->pte_p) pmap_install_pte(vhpte, pte); - - critical_exit(c); } /* @@ -1027,7 +1021,6 @@ pmap_remove_vhpt(vm_offset_t va) struct ia64_lpte *lpte; struct ia64_lpte *vhpte; u_int64_t tag; - critical_t c = critical_enter(); int error = ENOENT; vhpte = (struct ia64_lpte *) ia64_thash(va); @@ -1078,7 +1071,6 @@ pmap_remove_vhpt(vm_offset_t va) pmap_vhpt_resident--; error = 0; done: - critical_exit(c); return error; } @@ -1090,7 +1082,6 @@ pmap_find_vhpt(vm_offset_t va) { struct ia64_lpte *pte; u_int64_t tag; - critical_t c = critical_enter(); pte = (struct ia64_lpte *) ia64_thash(va); if (!pte->pte_chain) { @@ -1111,7 +1102,6 @@ pmap_find_vhpt(vm_offset_t va) } done: - critical_exit(c); return pte; } @@ -1492,6 +1482,8 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { pmap_t oldpmap; vm_offset_t va; + pv_entry_t pv; + struct ia64_lpte *pte; if (pmap == NULL) return; @@ -1512,13 +1504,25 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) return; } - for (va = sva; va < eva; va = va += PAGE_SIZE) { - struct ia64_lpte *pte; - - pte = pmap_find_vhpt(va); - if (pte) { - pmap_remove_pte(pmap, pte, va, 0, 1); - pmap_invalidate_page(pmap, va); + if (pmap->pm_stats.resident_count < ((eva - sva) >> PAGE_SHIFT)) { + for (pv = TAILQ_FIRST(&pmap->pm_pvlist); + pv; + pv = TAILQ_NEXT(pv, pv_plist)) { + va = pv->pv_va; + if (va >= sva && va < eva) { + pte = pmap_find_vhpt(va); + pmap_remove_pte(pmap, pte, va, pv, 1); + pmap_invalidate_page(pmap, va); + } + } + + } else { + for (va = sva; va < eva; va = va += PAGE_SIZE) { + pte = pmap_find_vhpt(va); + if (pte) { + pmap_remove_pte(pmap, pte, va, 0, 1); + pmap_invalidate_page(pmap, va); + } } } |