aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-02-04 10:48:02 -0500
committerIngo Molnar <mingo@elte.hu>2008-02-04 10:48:02 -0500
commitedd6bcd8209c31b91e1fbc112a756475091c483d (patch)
tree00495abdaa8343e34d8a6dfbd7825b10e85fd053 /include/asm-x86
parenta67ad9c9f82342a9b320fdad204a490727ef4a18 (diff)
x86: pud_clear: only reload cr3 if necessary
Rather than unconditionally reloading cr3, only do so if the pud we're updating is within the active pgd. This eliminates TLB flushes most of the time. The performance-critical uses of pud_clear are during execve and exit, but in those cases cr3 is referring to some other pagetable. The only other use of pud_clear is during a large (1Gbyte+) munmap, and those are sufficiently rare that a couple of cr3 reloads won't hurt. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86')
-rw-r--r--include/asm-x86/pgtable-3level.h11
1 files changed, 7 insertions, 4 deletions
diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
index ed4c6f0e57ec..ad71960bca3a 100644
--- a/include/asm-x86/pgtable-3level.h
+++ b/include/asm-x86/pgtable-3level.h
@@ -93,17 +93,20 @@ static inline void native_pmd_clear(pmd_t *pmd)
93 93
94static inline void pud_clear(pud_t *pudp) 94static inline void pud_clear(pud_t *pudp)
95{ 95{
96 unsigned long pgd;
97
96 set_pud(pudp, __pud(0)); 98 set_pud(pudp, __pud(0));
97 99
98 /* 100 /*
99 * Pentium-II erratum A13: in PAE mode we explicitly have to flush 101 * Pentium-II erratum A13: in PAE mode we explicitly have to flush
100 * the TLB via cr3 if the top-level pgd is changed... 102 * the TLB via cr3 if the top-level pgd is changed...
101 * 103 *
102 * XXX I don't think we need to worry about this here, since 104 * Make sure the pud entry we're updating is within the
103 * when clearing the pud, the calling code needs to flush the 105 * current pgd to avoid unnecessary TLB flushes.
104 * tlb anyway. But do it now for safety's sake. - jsgf
105 */ 106 */
106 write_cr3(read_cr3()); 107 pgd = read_cr3();
108 if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
109 write_cr3(pgd);
107} 110}
108 111
109#define pud_page(pud) \ 112#define pud_page(pud) \