From 17081102a6e0fe32cf47cdbdf8f2e9ab55273b08 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 31 Jan 2010 20:34:36 +0000 Subject: [PATCH] powerpc: Convert global "BAD" interrupt to per cpu spurious I often get asked if BAD interrupts are really bad. On some boxes (eg IBM machines running a hypervisor) there are valid cases where are presented with an interrupt that is not for us. These cases are common enough to show up as thousands of BAD interrupts a day. Tone them down by calling them spurious. Since they can be a significant cause of OS jitter, we may as well log them per cpu so we know where they are occurring. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hardirq.h | 4 +--- arch/powerpc/kernel/irq.c | 19 +++++++------------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index cd2d4be..3147a29 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h @@ -9,6 +9,7 @@ typedef struct { unsigned int timer_irqs; unsigned int pmu_irqs; unsigned int mce_exceptions; + unsigned int spurious_irqs; } ____cacheline_aligned irq_cpustat_t; DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); @@ -25,7 +26,4 @@ static inline void ack_bad_irq(unsigned int irq) extern u64 arch_irq_stat_cpu(unsigned int cpu); #define arch_irq_stat_cpu arch_irq_stat_cpu -extern u64 arch_irq_stat(void); -#define arch_irq_stat arch_irq_stat - #endif /* _ASM_POWERPC_HARDIRQ_H */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 7105052..9ae77e5 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -77,7 +77,6 @@ DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); EXPORT_PER_CPU_SYMBOL(irq_stat); int __irq_offset_value; -static int ppc_spurious_interrupts; #ifdef CONFIG_PPC32 EXPORT_SYMBOL(__irq_offset_value); @@ -201,6 +200,11 @@ static int show_other_interrupts(struct seq_file *p, int prec) seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs); seq_printf(p, " Local timer interrupts\n"); + seq_printf(p, "%*s: ", prec, "SPU"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs); + seq_printf(p, " Spurious interrupts\n"); + seq_printf(p, "%*s: ", prec, "CNT"); for_each_online_cpu(j) seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs); @@ -211,8 +215,6 @@ static int show_other_interrupts(struct seq_file *p, int prec) seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); seq_printf(p, " Machine check exceptions\n"); - seq_printf(p, "%*s: %10u\n", prec, "BAD", ppc_spurious_interrupts); - return 0; } @@ -282,13 +284,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += per_cpu(irq_stat, cpu).pmu_irqs; sum += per_cpu(irq_stat, cpu).mce_exceptions; - - return sum; -} - -u64 arch_irq_stat(void) -{ - u64 sum = ppc_spurious_interrupts; + sum += per_cpu(irq_stat, cpu).spurious_irqs; return sum; } @@ -404,8 +400,7 @@ void do_IRQ(struct pt_regs *regs) if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) handle_one_irq(irq); else if (irq != NO_IRQ_IGNORE) - /* That's not SMP safe ... but who cares ? */ - ppc_spurious_interrupts++; + __get_cpu_var(irq_stat).spurious_irqs++; irq_exit(); set_irq_regs(old_regs); -- 2.7.4