summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2009-07-23 19:43:23 +0000
committeralc <alc@FreeBSD.org>2009-07-23 19:43:23 +0000
commitfc8defe5dd957eaee1f1c841d45804df5bbf20f5 (patch)
tree89dd5290fb4605fe86dfd8b14e8a0588df7b5ea9
parent28f5cdcb2a9e30a281f1e58946fa9f1710f07cad (diff)
downloadFreeBSD-src-fc8defe5dd957eaee1f1c841d45804df5bbf20f5.zip
FreeBSD-src-fc8defe5dd957eaee1f1c841d45804df5bbf20f5.tar.gz
Eliminate unnecessary cache and TLB flushes by pmap_change_attr(). (This
optimization was implemented in the amd64 version roughly 1 year ago.) Approved by: re (kensmith)
-rw-r--r--sys/i386/i386/pmap.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index b973d0d..cbcb937 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -4482,6 +4482,7 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
pt_entry_t *pte;
u_int opte, npte;
pd_entry_t *pde;
+ boolean_t changed;
base = trunc_page(va);
offset = va & PAGE_MASK;
@@ -4505,6 +4506,8 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
return (EINVAL);
}
+ changed = FALSE;
+
/*
* Ok, all the pages exist and are 4k, so run through them updating
* their cache mode.
@@ -4522,6 +4525,8 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
npte |= pmap_cache_bits(mode, 0);
} while (npte != opte &&
!atomic_cmpset_int((u_int *)pte, opte, npte));
+ if (npte != opte)
+ changed = TRUE;
tmpva += PAGE_SIZE;
size -= PAGE_SIZE;
}
@@ -4530,10 +4535,12 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
* Flush CPU caches to make sure any data isn't cached that shouldn't
* be, etc.
*/
- pmap_invalidate_range(kernel_pmap, base, tmpva);
- /* If "Self Snoop" is supported, do nothing. */
- if (!(cpu_feature & CPUID_SS))
- pmap_invalidate_cache();
+ if (changed) {
+ pmap_invalidate_range(kernel_pmap, base, tmpva);
+ /* If "Self Snoop" is supported, do nothing. */
+ if (!(cpu_feature & CPUID_SS))
+ pmap_invalidate_cache();
+ }
return (0);
}
OpenPOWER on IntegriCloud