]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
x86/mm: Avoid superflous leave_mm() in the TLB flush path
authorShaohua Li <shaohua.li@intel.com>
Tue, 15 Nov 2011 22:49:02 +0000 (14:49 -0800)
committerIngo Molnar <mingo@elte.hu>
Mon, 5 Dec 2011 16:11:50 +0000 (17:11 +0100)
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: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
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);