x86: Distinguish TLB shootdown interrupts from other functions call interrupts
authorTomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com>
Wed, 26 Sep 2012 02:11:28 +0000 (11:11 +0900)
committerH. Peter Anvin <hpa@linux.intel.com>
Fri, 28 Sep 2012 05:52:34 +0000 (22:52 -0700)
As TLB shootdown requests to other CPU cores are now using function call
interrupts, TLB shootdowns entry in /proc/interrupts is always shown as 0.

This behavior change was introduced by commit 52aec3308db8 ("x86/tlb:
replace INVALIDATE_TLB_VECTOR by CALL_FUNCTION_VECTOR").

This patch reverts TLB shootdowns entry in /proc/interrupts to count TLB
shootdowns separately from the other function call interrupts.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com>
Link: http://lkml.kernel.org/r/20120926021128.22212.20440.stgit@hpxw
Acked-by: Alex Shi <alex.shi@intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/include/asm/hardirq.h
arch/x86/kernel/irq.c
arch/x86/mm/tlb.c

index d3895dbf4ddb531da7bbc44ebd59f9a1032475fa..81f04cee5f741226b6e23e45bcab7874bff29e62 100644 (file)
@@ -18,6 +18,10 @@ typedef struct {
 #ifdef CONFIG_SMP
        unsigned int irq_resched_count;
        unsigned int irq_call_count;
+       /*
+        * irq_tlb_count is double-counted in irq_call_count, so it must be
+        * subtracted from irq_call_count when displaying irq_call_count
+        */
        unsigned int irq_tlb_count;
 #endif
 #ifdef CONFIG_X86_THERMAL_VECTOR
index 1f5f1d5d2a022b21a6871c083af70f09b9def90f..355b13f6de8d1b913e9d9e3ca828a6b2a4b56579 100644 (file)
@@ -92,7 +92,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "  Rescheduling interrupts\n");
        seq_printf(p, "%*s: ", prec, "CAL");
        for_each_online_cpu(j)
-               seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
+               seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
+                                       irq_stats(j)->irq_tlb_count);
        seq_printf(p, "  Function call interrupts\n");
        seq_printf(p, "%*s: ", prec, "TLB");
        for_each_online_cpu(j)
@@ -147,7 +148,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 #ifdef CONFIG_SMP
        sum += irq_stats(cpu)->irq_resched_count;
        sum += irq_stats(cpu)->irq_call_count;
-       sum += irq_stats(cpu)->irq_tlb_count;
 #endif
 #ifdef CONFIG_X86_THERMAL_VECTOR
        sum += irq_stats(cpu)->irq_thermal_count;
index a085c560b4a53367ffcb47ee6494e33124a44ff2..0777f042e4002e695b316c99889b594daebc5448 100644 (file)
@@ -98,6 +98,8 @@ static void flush_tlb_func(void *info)
 {
        struct flush_tlb_info *f = info;
 
+       inc_irq_stat(irq_tlb_count);
+
        if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
                return;