From 47b9dbd431ad5b10e070416beed74a4e562e91ee Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Apr 1999 04:52:27 +0000 Subject: [PATCH] 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. --- sys/amd64/amd64/pmap.c | 25 +++++-------------------- sys/i386/i386/pmap.c | 25 +++++-------------------- 2 files changed, 10 insertions(+), 40 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index c630306eb06..58c7730a48a 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/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; } /* diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index c630306eb06..58c7730a48a 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; } /*