Skip to content

Commit

Permalink
x86: pud_clear: only reload cr3 if necessary
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeremy Fitzhardinge authored and Ingo Molnar committed Feb 4, 2008
1 parent a67ad9c commit edd6bcd
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions include/asm-x86/pgtable-3level.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,20 @@ static inline void native_pmd_clear(pmd_t *pmd)

static inline void pud_clear(pud_t *pudp)
{
unsigned long pgd;

set_pud(pudp, __pud(0));

/*
* Pentium-II erratum A13: in PAE mode we explicitly have to flush
* the TLB via cr3 if the top-level pgd is changed...
*
* XXX I don't think we need to worry about this here, since
* when clearing the pud, the calling code needs to flush the
* tlb anyway. But do it now for safety's sake. - jsgf
* Make sure the pud entry we're updating is within the
* current pgd to avoid unnecessary TLB flushes.
*/
write_cr3(read_cr3());
pgd = read_cr3();
if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
write_cr3(pgd);
}

#define pud_page(pud) \
Expand Down

0 comments on commit edd6bcd

Please sign in to comment.