diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | i386/i386/proc_reg.h | 11 | ||||
-rw-r--r-- | i386/intel/pmap.c | 9 |
3 files changed, 25 insertions, 4 deletions
@@ -1,3 +1,12 @@ +2009-02-26 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/prog_reg.h (invlpg_linear): Rename macro into... + (invlpg_linear_range): ... this. + (invlpg_linear): New macro. + * i386/intel/pmap.c (INVALIDATE_TLB): Call invlpg_linear instead + of flush_tlb when e - S is compile-time known to be PAGE_SIZE, + instead of run-time known to be less than 32 * PAGE_SIZE. + 2009-01-05 Samuel Thibault <samuel.thibault@ens-lyon.org> * i386/i386/gdt.h (LINEAR_DS): New macro. diff --git a/i386/i386/proc_reg.h b/i386/i386/proc_reg.h index 11a21cf..d9f32bc 100644 --- a/i386/i386/proc_reg.h +++ b/i386/i386/proc_reg.h @@ -142,7 +142,16 @@ set_eflags(unsigned eflags) asm volatile("invlpg (%0)" : : "r" (addr)); \ }) -#define invlpg_linear(start, end) \ +#define invlpg_linear(start) \ + ({ \ + asm volatile( \ + "movw %w1,%%es\n" \ + "\tinvlpg %%es:(%0)\n" \ + "\tmovw %w2,%%es" \ + :: "r" (start), "q" (LINEAR_DS), "q" (KERNEL_DS)); \ + }) + +#define invlpg_linear_range(start, end) \ ({ \ register unsigned long var = trunc_page(start); \ asm volatile( \ diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c index d46f645..d57df92 100644 --- a/i386/intel/pmap.c +++ b/i386/intel/pmap.c @@ -332,11 +332,14 @@ lock_data_t pmap_system_lock; #define MAX_TBIS_SIZE 32 /* > this -> TBIA */ /* XXX */ #if 0 +/* It is hard to know when a TLB flush becomes less expensive than a bunch of + * invlpgs. But it surely is more expensive than just one invlpg. */ #define INVALIDATE_TLB(s, e) { \ - if (((e) - (s)) > 32 * PAGE_SIZE) \ - flush_tlb(); \ + if (__builtin_constant_p((e) - (s)) + && (e) - (s) == PAGE_SIZE) + invlpg_linear(s); \ else \ - invlpg_linear(s, e); \ + flush_tlb(); \ } #else #define INVALIDATE_TLB(s, e) flush_tlb() |