Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Distinguish TLB shootdown interrupts from other functions call interrupts

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>

authored by

Tomoki Sekiyama and committed by
H. Peter Anvin
fd0f5869 d4c9dbc6

+8 -2
+4
arch/x86/include/asm/hardirq.h
··· 18 18 #ifdef CONFIG_SMP 19 19 unsigned int irq_resched_count; 20 20 unsigned int irq_call_count; 21 + /* 22 + * irq_tlb_count is double-counted in irq_call_count, so it must be 23 + * subtracted from irq_call_count when displaying irq_call_count 24 + */ 21 25 unsigned int irq_tlb_count; 22 26 #endif 23 27 #ifdef CONFIG_X86_THERMAL_VECTOR
+2 -2
arch/x86/kernel/irq.c
··· 92 92 seq_printf(p, " Rescheduling interrupts\n"); 93 93 seq_printf(p, "%*s: ", prec, "CAL"); 94 94 for_each_online_cpu(j) 95 - seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); 95 + seq_printf(p, "%10u ", irq_stats(j)->irq_call_count - 96 + irq_stats(j)->irq_tlb_count); 96 97 seq_printf(p, " Function call interrupts\n"); 97 98 seq_printf(p, "%*s: ", prec, "TLB"); 98 99 for_each_online_cpu(j) ··· 148 147 #ifdef CONFIG_SMP 149 148 sum += irq_stats(cpu)->irq_resched_count; 150 149 sum += irq_stats(cpu)->irq_call_count; 151 - sum += irq_stats(cpu)->irq_tlb_count; 152 150 #endif 153 151 #ifdef CONFIG_X86_THERMAL_VECTOR 154 152 sum += irq_stats(cpu)->irq_thermal_count;
+2
arch/x86/mm/tlb.c
··· 98 98 { 99 99 struct flush_tlb_info *f = info; 100 100 101 + inc_irq_stat(irq_tlb_count); 102 + 101 103 if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) 102 104 return; 103 105