diff options
author | alc <alc@FreeBSD.org> | 1999-04-06 04:52:27 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 1999-04-06 04:52:27 +0000 |
commit | 94c3a8d12f3962371ab018cc5870594c6426240a (patch) | |
tree | 2a3bda0e80647489d562c43c31e2396f12f3d4bc /sys/i386 | |
parent | 9f884254c7708e5c45656623b738c91b71cc946a (diff) | |
download | FreeBSD-src-94c3a8d12f3962371ab018cc5870594c6426240a.zip FreeBSD-src-94c3a8d12f3962371ab018cc5870594c6426240a.tar.gz |
Two changes to pmap_remove_all:
1. Switch to pmap_TLB_invalidate from invltlb, eliminating a full TLB
flush where a single-page flush suffices. (Also, this eliminates some
unnecessary IPIs.)
2. Use "loadandclear" to update the pte, eliminating a race condition
on SMPs.
Change #2 should be committed to -STABLE.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/pmap.c | 25 |
1 files changed, 5 insertions, 20 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index c630306..58c7730 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.226 1999/04/02 17:59:38 alc Exp $ + * $Id: pmap.c,v 1.227 1999/04/05 19:38:28 julian Exp $ */ /* @@ -1964,10 +1964,8 @@ pmap_remove_all(pa) register pv_entry_t pv; pv_table_t *ppv; register unsigned *pte, tpte; - int update_needed; int s; - update_needed = 0; #if defined(PMAP_DIAGNOSTIC) /* * XXX this makes pmap_page_protect(NONE) illegal for non-managed @@ -1981,12 +1979,11 @@ pmap_remove_all(pa) s = splvm(); ppv = pa_to_pvh(pa); while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) { - pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); - pv->pv_pmap->pm_stats.resident_count--; - tpte = *pte; - *pte = 0; + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); + + tpte = loadandclear(pte); if (tpte & PG_W) pv->pv_pmap->pm_stats.wired_count--; @@ -2007,15 +2004,7 @@ pmap_remove_all(pa) if (pmap_track_modified(pv->pv_va)) vm_page_dirty(ppv->pv_vm_page); } -#ifdef SMP - update_needed = 1; -#else - if (!update_needed && - ((!curproc || (vmspace_pmap(curproc->p_vmspace) == pv->pv_pmap)) || - (pv->pv_pmap == kernel_pmap))) { - update_needed = 1; - } -#endif + pmap_TLB_invalidate(pv->pv_pmap, pv->pv_va); TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist); TAILQ_REMOVE(&ppv->pv_list, pv, pv_list); @@ -2026,11 +2015,7 @@ pmap_remove_all(pa) vm_page_flag_clear(ppv->pv_vm_page, PG_MAPPED | PG_WRITEABLE); - if (update_needed) - invltlb(); - splx(s); - return; } /* |