]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
x86: tlb flush avoid superflous leave_mm()
authorShaohua Li <shaohua.li@intel.com>
Wed, 5 Oct 2011 00:42:28 +0000 (11:42 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 7 Oct 2011 06:06:23 +0000 (17:06 +1100)
If just one page VA tlb is required to be flushed and current task is in
lazy TLB state, doing leave_mm() is superfluous because it flushes the
whole TLB.  This can reduce some TLB miss.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/x86/mm/tlb.c

index d6c0418c3e4711795158b52e57b2fa337848d03c..304166557366123f9002b2449b6f1d20577502a7 100644 (file)
@@ -153,13 +153,13 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
                 */
 
        if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) {
-               if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
-                       if (f->flush_va == TLB_FLUSH_ALL)
+               if (f->flush_va == TLB_FLUSH_ALL) {
+                       if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
                                local_flush_tlb();
                        else
-                               __flush_tlb_one(f->flush_va);
+                               leave_mm(cpu);
                } else
-                       leave_mm(cpu);
+                       __flush_tlb_one(f->flush_va);
        }
 out:
        ack_APIC_irq();
@@ -306,12 +306,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
 
        preempt_disable();
 
-       if (current->active_mm == mm) {
-               if (current->mm)
-                       __flush_tlb_one(va);
-               else
-                       leave_mm(smp_processor_id());
-       }
+       if (current->active_mm == mm)
+               __flush_tlb_one(va);
 
        if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
                flush_tlb_others(mm_cpumask(mm), mm, va);