svn commit: r311902 - in head/sys: amd64/amd64 i386/i386
Mark Johnston
markj at FreeBSD.org
Tue Jan 10 21:52:49 UTC 2017
Author: markj
Date: Tue Jan 10 21:52:48 2017
New Revision: 311902
URL: https://svnweb.freebsd.org/changeset/base/311902
Log:
Coalesce TLB shootdowns of global PTEs in pmap_advise() on x86.
We would previously invalidate such entries individually, resulting in more
IPIs than necessary.
Reviewed by: alc, kib
MFC after: 3 weeks
Differential Revision: https://reviews.freebsd.org/D9094
Modified:
head/sys/amd64/amd64/pmap.c
head/sys/i386/i386/pmap.c
Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c Tue Jan 10 21:41:28 2017 (r311901)
+++ head/sys/amd64/amd64/pmap.c Tue Jan 10 21:52:48 2017 (r311902)
@@ -6010,7 +6010,7 @@ pmap_advise(pmap_t pmap, vm_offset_t sva
pdp_entry_t *pdpe;
pd_entry_t oldpde, *pde;
pt_entry_t *pte, PG_A, PG_G, PG_M, PG_RW, PG_V;
- vm_offset_t va_next;
+ vm_offset_t va, va_next;
vm_page_t m;
boolean_t anychanged;
@@ -6090,11 +6090,11 @@ pmap_advise(pmap_t pmap, vm_offset_t sva
}
if (va_next > eva)
va_next = eva;
+ va = va_next;
for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++,
sva += PAGE_SIZE) {
- if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED |
- PG_V))
- continue;
+ if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED | PG_V))
+ goto maybe_invlrng;
else if ((*pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
if (advice == MADV_DONTNEED) {
/*
@@ -6109,12 +6109,22 @@ pmap_advise(pmap_t pmap, vm_offset_t sva
} else if ((*pte & PG_A) != 0)
atomic_clear_long(pte, PG_A);
else
- continue;
- if ((*pte & PG_G) != 0)
- pmap_invalidate_page(pmap, sva);
- else
+ goto maybe_invlrng;
+
+ if ((*pte & PG_G) != 0) {
+ if (va == va_next)
+ va = sva;
+ } else
anychanged = TRUE;
+ continue;
+maybe_invlrng:
+ if (va != va_next) {
+ pmap_invalidate_range(pmap, va, sva);
+ va = va_next;
+ }
}
+ if (va != va_next)
+ pmap_invalidate_range(pmap, va, sva);
}
if (anychanged)
pmap_invalidate_all(pmap);
Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c Tue Jan 10 21:41:28 2017 (r311901)
+++ head/sys/i386/i386/pmap.c Tue Jan 10 21:52:48 2017 (r311902)
@@ -4905,7 +4905,7 @@ pmap_advise(pmap_t pmap, vm_offset_t sva
{
pd_entry_t oldpde, *pde;
pt_entry_t *pte;
- vm_offset_t pdnxt;
+ vm_offset_t va, pdnxt;
vm_page_t m;
boolean_t anychanged, pv_lists_locked;
@@ -4966,11 +4966,11 @@ resume:
}
if (pdnxt > eva)
pdnxt = eva;
+ va = pdnxt;
for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
sva += PAGE_SIZE) {
- if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED |
- PG_V))
- continue;
+ if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED | PG_V))
+ goto maybe_invlrng;
else if ((*pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
if (advice == MADV_DONTNEED) {
/*
@@ -4985,12 +4985,21 @@ resume:
} else if ((*pte & PG_A) != 0)
atomic_clear_int((u_int *)pte, PG_A);
else
- continue;
- if ((*pte & PG_G) != 0)
- pmap_invalidate_page(pmap, sva);
- else
+ goto maybe_invlrng;
+ if ((*pte & PG_G) != 0) {
+ if (va == pdnxt)
+ va = sva;
+ } else
anychanged = TRUE;
+ continue;
+maybe_invlrng:
+ if (va != pdnxt) {
+ pmap_invalidate_range(pmap, va, sva);
+ va = pdnxt;
+ }
}
+ if (va != pdnxt)
+ pmap_invalidate_range(pmap, va, sva);
}
if (anychanged)
pmap_invalidate_all(pmap);
More information about the svn-src-head
mailing list