On Thu, 2007-07-26 at 11:56 -0700, H. Peter Anvin wrote: 
> Joe Korty wrote:
> > Create /proc/all-interrupts for some architectures.
> > 
> > Create a version of /proc/interrupts that displays _every_
> > IRQ vector, not just those that someone thought might be
> > interesting, and add an entry in the commentary column
> > for those vectors which lacked such a comment.
> > 
> > Rationale: /proc/interrupts is not truly useful unless it
> > displays every IRQ vector, not just those somebody thought
> > would be interesting.  For example, since /proc/interrupts
> > does not display the rescheduling interrupt, the occurance
> > of rescheduling interrupt floods ends up affecting
> > latencies, yet without an entry in /proc/interrupts, it
> > is difficult to discern why latencies are being affected.
> > 
> > Rather than modify /proc/interrupts, this patch creates
> > a new version of /proc/interrupts, on the off-chance
> > that adding new lines to /proc/interrupts, and appending
> > new fields to the end of old lines, might break some
> > longstanding script.  However, these kinds of changes
> > traditionally do not affect scripts, so it might be
> > reasonable to fold /proc/all-interrupts back into
> > /proc/interrupts.
> 
> I think that would be the right thing to do.  We have added things to
> /proc/interrupts in the past.
> 
Hi Andrew,

Would it make sense to drop this patch into -mm for feedback?

Thanks,

Sven
--- Begin Message ---
Add missing IRQs to /proc/interrupts.

/proc/interrupts is not truly useful unless it displays
every IRQ vector, not just those somebody thought
would be interesting.  For example, since the default
/proc/interrupts setup did not display the rescheduling
interrupt, the occurance of rescheduling interrupt floods
ends up affecting latencies, yet without an entry in
/proc/interrupts, it is difficult to discern why latencies
are being affected.

Also does a silly little expansion of the 'ERR:' display
to be per cpu.  This makes its layout identical to all
the other display lines in /proc/interrupts.

Signed-off-by: Joe Korty <[EMAIL PROTECTED]>

Index: 2.6.22.1-rt8/arch/i386/kernel/apic.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/apic.c   2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/i386/kernel/apic.c        2007-07-25 16:07:43.000000000 
-0400
@@ -1268,6 +1268,8 @@
 {
        unsigned long v;
 
+       atomic_inc(&__get_cpu_var(irq_spur_counts));
+
        irq_enter();
        /*
         * Check if this really is a spurious interrupt and ACK it
@@ -1297,7 +1299,7 @@
        apic_write(APIC_ESR, 0);
        v1 = apic_read(APIC_ESR);
        ack_APIC_irq();
-       atomic_inc(&irq_err_count);
+       atomic_inc(&__get_cpu_var(irq_err_counts));
 
        /* Here is what the APIC error bits mean:
           0: Send CS error
Index: 2.6.22.1-rt8/arch/i386/kernel/cpu/mcheck/p4.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/cpu/mcheck/p4.c  2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/arch/i386/kernel/cpu/mcheck/p4.c       2007-07-25 
16:07:43.000000000 -0400
@@ -60,6 +60,7 @@
 fastcall void smp_thermal_interrupt(struct pt_regs *regs)
 {
        irq_enter();
+       atomic_inc(&__get_cpu_var(irq_thermal_counts));
        vendor_thermal_interrupt(regs);
        irq_exit();
 }
Index: 2.6.22.1-rt8/arch/i386/kernel/i8259.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/i8259.c  2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/i386/kernel/i8259.c       2007-07-25 16:07:43.000000000 
-0400
@@ -209,7 +209,7 @@
                        printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", 
irq);
                        spurious_irq_mask |= irqmask;
                }
-               atomic_inc(&irq_err_count);
+               atomic_inc(&__get_cpu_var(irq_err_counts));
                /*
                 * Theoretically we do not have to handle this IRQ,
                 * but in Linux this does not cause problems and is
Index: 2.6.22.1-rt8/arch/i386/kernel/io_apic.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/io_apic.c        2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/arch/i386/kernel/io_apic.c     2007-07-25 16:07:43.000000000 
-0400
@@ -51,7 +51,6 @@
 #include "io_ports.h"
 
 int (*ioapic_renumber_irq)(int ioapic, int irq);
-atomic_t irq_mis_count;
 
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
@@ -2031,7 +2030,7 @@
        ack_APIC_irq();
 
        if (!(v & (1 << (i & 0x1f)))) {
-               atomic_inc(&irq_mis_count);
+               atomic_inc(&__get_cpu_var(irq_mis_counts));
                spin_lock(&ioapic_lock);
                /* mask = 1, trigger = 0 */
                __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000);
Index: 2.6.22.1-rt8/arch/i386/kernel/irq.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/irq.c    2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/i386/kernel/irq.c 2007-07-25 16:23:12.000000000 -0400
@@ -252,7 +252,13 @@
  * Interrupt statistics:
  */
 
-atomic_t irq_err_count;
+DEFINE_PER_CPU(atomic_t, irq_resched_counts);
+DEFINE_PER_CPU(atomic_t, irq_call_counts);
+DEFINE_PER_CPU(atomic_t, irq_spur_counts);
+DEFINE_PER_CPU(atomic_t, irq_tlb_counts);
+DEFINE_PER_CPU(atomic_t, irq_thermal_counts);
+DEFINE_PER_CPU(atomic_t, irq_err_counts);
+DEFINE_PER_CPU(atomic_t, irq_mis_counts);
 
 /*
  * /proc/interrupts printing:
@@ -305,9 +311,60 @@
                                per_cpu(irq_stat,j).apic_timer_irqs);
                seq_putc(p, '\n');
 #endif
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#if defined(CONFIG_X86_IO_APIC)
-               seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+#ifdef CONFIG_SMP
+#ifdef RESCHEDULE_VECTOR
+               seq_printf(p, "RES: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_resched_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef CONFIG_SMP
+#ifdef CALL_FUNCTION_VECTOR
+               seq_printf(p, "CAL: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_call_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef CONFIG_SMP
+#ifdef INVALIDATE_TLB_VECTOR
+               seq_printf(p, "TLB: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_tlb_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef THERMAL_APIC_VECTOR
+               seq_printf(p, "TRM: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_thermal_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef SPURIOUS_APIC_VECTOR
+               seq_printf(p, "SPU: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_spur_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef ERROR_APIC_VECTOR
+               seq_printf(p, "ERR: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_err_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#if defined(CONFIG_X86_IO_APIC) && defined(APIC_MISMATCH_DEBUG)
+               seq_printf(p, "MIS: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                               atomic_read(&per_cpu(irq_mis_counts, j)));
+               seq_putc(p, '\n');
 #endif
        }
        return 0;
Index: 2.6.22.1-rt8/arch/i386/kernel/smp.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/i386/kernel/smp.c    2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/i386/kernel/smp.c 2007-07-25 16:07:43.000000000 -0400
@@ -315,6 +315,7 @@
        unsigned long cpu;
 
        cpu = get_cpu();
+       atomic_inc(&__get_cpu_var(irq_tlb_counts));
 
        if (!cpu_isset(cpu, flush_cpumask))
                goto out;
@@ -658,6 +659,7 @@
 {
        trace_special(regs->eip, 0, 0);
        ack_APIC_irq();
+       atomic_inc(&__get_cpu_var(irq_resched_counts));
        set_tsk_need_resched(current);
 }
 
@@ -668,6 +670,7 @@
        int wait = call_data->wait;
 
        ack_APIC_irq();
+       atomic_inc(&__get_cpu_var(irq_call_counts));
        /*
         * Notify initiating CPU that I've grabbed the data and am
         * about to execute the function
Index: 2.6.22.1-rt8/arch/x86_64/kernel/apic.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/apic.c 2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/apic.c      2007-07-25 16:07:43.000000000 
-0400
@@ -1099,6 +1099,9 @@
 asmlinkage void smp_spurious_interrupt(void)
 {
        unsigned int v;
+
+       atomic_inc(&__get_cpu_var(irq_spur_counts));
+
        exit_idle();
        irq_enter();
        /*
@@ -1127,7 +1130,7 @@
        apic_write(APIC_ESR, 0);
        v1 = apic_read(APIC_ESR);
        ack_APIC_irq();
-       atomic_inc(&irq_err_count);
+       atomic_inc(&__get_cpu_var(irq_err_counts));
 
        /* Here is what the APIC error bits mean:
           0: Send CS error
Index: 2.6.22.1-rt8/arch/x86_64/kernel/i8259.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/i8259.c        2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/i8259.c     2007-07-25 16:07:43.000000000 
-0400
@@ -273,7 +273,7 @@
                        printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", 
irq);
                        spurious_irq_mask |= irqmask;
                }
-               atomic_inc(&irq_err_count);
+               atomic_inc(&__get_cpu_var(irq_err_counts));
                /*
                 * Theoretically we do not have to handle this IRQ,
                 * but in Linux this does not cause problems and is
Index: 2.6.22.1-rt8/arch/x86_64/kernel/irq.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/irq.c  2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/irq.c       2007-07-25 16:23:12.000000000 
-0400
@@ -20,7 +20,18 @@
 #include <asm/idle.h>
 #include <asm/smp.h>
 
-atomic_t irq_err_count;
+DEFINE_PER_CPU(atomic_t, irq_resched_counts);
+DEFINE_PER_CPU(atomic_t, irq_call_counts);
+DEFINE_PER_CPU(atomic_t, irq_spur_counts);
+DEFINE_PER_CPU(atomic_t, irq_tlb_counts);
+DEFINE_PER_CPU(atomic_t, irq_threshold_counts);
+DEFINE_PER_CPU(atomic_t, irq_thermal_counts);
+DEFINE_PER_CPU(atomic_t, irq_err_counts);
+#ifdef CONFIG_X86_IO_APIC
+#ifdef APIC_MISMATCH_DEBUG
+DEFINE_PER_CPU(atomic_t, irq_mis_counts);
+#endif
+#endif
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 /*
@@ -93,7 +104,62 @@
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
                seq_putc(p, '\n');
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+#ifdef CONFIG_SMP
+#ifdef RESCHEDULE_VECTOR
+               seq_printf(p, "RES: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_resched_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef CONFIG_SMP
+#ifdef CALL_FUNCTION_VECTOR
+               seq_printf(p, "CAL: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_call_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef CONFIG_SMP
+#ifdef INVALIDATE_TLB_VECTOR_START
+               seq_printf(p, "TLB: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_tlb_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
+#ifdef THERMAL_APIC_VECTOR
+               seq_printf(p, "TRM: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_thermal_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef THRESHOLD_APIC_VECTOR
+               seq_printf(p, "THR: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_threshold_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef SPURIOUS_APIC_VECTOR
+               seq_printf(p, "SPU: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_spur_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef ERROR_APIC_VECTOR
+               seq_printf(p, "ERR: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_err_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#ifdef CONFIG_X86_IO_APIC
+#ifdef APIC_MISMATCH_DEBUG
+               seq_printf(p, "MIS: ");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", 
atomic_read(&per_cpu(irq_mis_counts, j)));
+               seq_putc(p, '\n');
+#endif
+#endif
        }
        return 0;
 }
Index: 2.6.22.1-rt8/arch/x86_64/kernel/mce_amd.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/mce_amd.c      2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/mce_amd.c   2007-07-25 16:07:43.000000000 
-0400
@@ -186,6 +186,8 @@
        exit_idle();
        irq_enter();
 
+       atomic_inc(&__get_cpu_var(irq_threshold_counts));
+
        memset(&m, 0, sizeof(m));
        rdtscll(m.tsc);
        m.cpu = smp_processor_id();
Index: 2.6.22.1-rt8/arch/x86_64/kernel/mce_intel.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/mce_intel.c    2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/mce_intel.c 2007-07-25 16:07:43.000000000 
-0400
@@ -21,6 +21,7 @@
 
        exit_idle();
        irq_enter();
+       atomic_inc(&__get_cpu_var(irq_thermal_counts));
 
        rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
        if (therm_throt_process(msr_val & 1))
Index: 2.6.22.1-rt8/include/asm-i386/apic.h
===================================================================
--- 2.6.22.1-rt8.orig/include/asm-i386/apic.h   2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/include/asm-i386/apic.h        2007-07-25 16:07:43.000000000 
-0400
@@ -7,6 +7,7 @@
 #include <asm/apicdef.h>
 #include <asm/processor.h>
 #include <asm/system.h>
+#include <asm/atomic.h>
 
 #define Dprintk(x...)
 
@@ -118,6 +119,9 @@
 
 extern void smp_send_nmi_allbutself(void);
 
+DECLARE_PER_CPU(atomic_t, irq_spur_counts);
+DECLARE_PER_CPU(atomic_t, irq_thermal_counts);
+
 #else /* !CONFIG_X86_LOCAL_APIC */
 static inline void lapic_shutdown(void) { }
 
Index: 2.6.22.1-rt8/include/asm-i386/hw_irq.h
===================================================================
--- 2.6.22.1-rt8.orig/include/asm-i386/hw_irq.h 2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/include/asm-i386/hw_irq.h      2007-07-25 16:07:43.000000000 
-0400
@@ -13,6 +13,7 @@
  */
 
 #include <linux/profile.h>
+#include <linux/percpu.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/sections.h>
@@ -58,8 +59,11 @@
 
 extern unsigned long io_apic_irqs;
 
-extern atomic_t irq_err_count;
-extern atomic_t irq_mis_count;
+DECLARE_PER_CPU(atomic_t, irq_resched_counts);
+DECLARE_PER_CPU(atomic_t, irq_call_counts);
+DECLARE_PER_CPU(atomic_t, irq_tlb_counts);
+DECLARE_PER_CPU(atomic_t, irq_err_counts);
+DECLARE_PER_CPU(atomic_t, irq_mis_counts);
 
 #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
Index: 2.6.22.1-rt8/include/asm-x86_64/apic.h
===================================================================
--- 2.6.22.1-rt8.orig/include/asm-x86_64/apic.h 2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/include/asm-x86_64/apic.h      2007-07-25 16:07:43.000000000 
-0400
@@ -6,6 +6,7 @@
 #include <asm/fixmap.h>
 #include <asm/apicdef.h>
 #include <asm/system.h>
+#include <asm/atomic.h>
 
 #define Dprintk(x...)
 
@@ -101,4 +102,7 @@
 extern unsigned boot_cpu_id;
 extern int local_apic_timer_c2_ok;
 
+DECLARE_PER_CPU(atomic_t, irq_spur_counts);
+DECLARE_PER_CPU(atomic_t, irq_thermal_counts);
+
 #endif /* __ASM_APIC_H */
Index: 2.6.22.1-rt8/include/asm-x86_64/hw_irq.h
===================================================================
--- 2.6.22.1-rt8.orig/include/asm-x86_64/hw_irq.h       2007-07-25 
16:07:23.000000000 -0400
+++ 2.6.22.1-rt8/include/asm-x86_64/hw_irq.h    2007-07-25 16:07:43.000000000 
-0400
@@ -123,8 +123,12 @@
 
 extern unsigned long io_apic_irqs;
 
-extern atomic_t irq_err_count;
-extern atomic_t irq_mis_count;
+DECLARE_PER_CPU(atomic_t, irq_resched_counts);
+DECLARE_PER_CPU(atomic_t, irq_call_counts);
+DECLARE_PER_CPU(atomic_t, irq_tlb_counts);
+DECLARE_PER_CPU(atomic_t, irq_threshold_counts);
+DECLARE_PER_CPU(atomic_t, irq_err_counts);
+DECLARE_PER_CPU(atomic_t, irq_mis_counts);
 
 #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
Index: 2.6.22.1-rt8/arch/x86_64/kernel/smp.c
===================================================================
--- 2.6.22.1-rt8.orig/arch/x86_64/kernel/smp.c  2007-07-25 16:07:23.000000000 
-0400
+++ 2.6.22.1-rt8/arch/x86_64/kernel/smp.c       2007-07-25 16:07:43.000000000 
-0400
@@ -133,6 +133,8 @@
        int sender;
        union smp_flush_state *f;
 
+       atomic_inc(&__get_cpu_var(irq_tlb_counts));
+
        cpu = smp_processor_id();
        /*
         * orig_rax contains the negated interrupt vector.
@@ -508,6 +510,7 @@
 asmlinkage void smp_reschedule_interrupt(void)
 {
        ack_APIC_irq();
+       atomic_inc(&__get_cpu_var(irq_resched_counts));
 }
 
 asmlinkage void smp_call_function_interrupt(void)
@@ -517,6 +520,7 @@
        int wait = call_data->wait;
 
        ack_APIC_irq();
+       atomic_inc(&__get_cpu_var(irq_call_counts));
        /*
         * Notify initiating CPU that I've grabbed the data and am
         * about to execute the function

--- End Message ---

Reply via email to