Skip to content

Commit

Permalink
x86: make /proc/stat account for all interrupts
Browse files Browse the repository at this point in the history
LAPIC interrupts, which don't go through the generic interrupt handling
code, aren't accounted for in /proc/stat. Hence this patch adds a
mechanism architectures can use to accordingly adjust the statistics.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Jan Beulich authored and Thomas Gleixner committed May 25, 2008
1 parent 75d3bce commit a2eddfa
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
38 changes: 38 additions & 0 deletions arch/x86/kernel/irq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,20 @@ int show_interrupts(struct seq_file *p, void *v)
per_cpu(irq_stat,j).irq_tlb_count);
seq_printf(p, " TLB shootdowns\n");
#endif
#ifdef CONFIG_X86_MCE
seq_printf(p, "TRM: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ",
per_cpu(irq_stat,j).irq_thermal_count);
seq_printf(p, " Thermal event interrupts\n");
#endif
#ifdef CONFIG_X86_LOCAL_APIC
seq_printf(p, "SPU: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ",
per_cpu(irq_stat,j).irq_spurious_count);
seq_printf(p, " Spurious interrupts\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));
Expand All @@ -331,6 +335,40 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
}

/*
* /proc/stat helpers
*/
u64 arch_irq_stat_cpu(unsigned int cpu)
{
u64 sum = nmi_count(cpu);

#ifdef CONFIG_X86_LOCAL_APIC
sum += per_cpu(irq_stat, cpu).apic_timer_irqs;
#endif
#ifdef CONFIG_SMP
sum += per_cpu(irq_stat, cpu).irq_resched_count;
sum += per_cpu(irq_stat, cpu).irq_call_count;
sum += per_cpu(irq_stat, cpu).irq_tlb_count;
#endif
#ifdef CONFIG_X86_MCE
sum += per_cpu(irq_stat, cpu).irq_thermal_count;
#endif
#ifdef CONFIG_X86_LOCAL_APIC
sum += per_cpu(irq_stat, cpu).irq_spurious_count;
#endif
return sum;
}

u64 arch_irq_stat(void)
{
u64 sum = atomic_read(&irq_err_count);

#ifdef CONFIG_X86_IO_APIC
sum += atomic_read(&irq_mis_count);
#endif
return sum;
}

#ifdef CONFIG_HOTPLUG_CPU
#include <mach_apic.h>

Expand Down
28 changes: 28 additions & 0 deletions arch/x86/kernel/irq_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
seq_printf(p, " TLB shootdowns\n");
#endif
#ifdef CONFIG_X86_MCE
seq_printf(p, "TRM: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->irq_thermal_count);
Expand All @@ -143,6 +144,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->irq_threshold_count);
seq_printf(p, " Threshold APIC interrupts\n");
#endif
seq_printf(p, "SPU: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->irq_spurious_count);
Expand All @@ -152,6 +154,32 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
}

/*
* /proc/stat helpers
*/
u64 arch_irq_stat_cpu(unsigned int cpu)
{
u64 sum = cpu_pda(cpu)->__nmi_count;

sum += cpu_pda(cpu)->apic_timer_irqs;
#ifdef CONFIG_SMP
sum += cpu_pda(cpu)->irq_resched_count;
sum += cpu_pda(cpu)->irq_call_count;
sum += cpu_pda(cpu)->irq_tlb_count;
#endif
#ifdef CONFIG_X86_MCE
sum += cpu_pda(cpu)->irq_thermal_count;
sum += cpu_pda(cpu)->irq_threshold_count;
#endif
sum += cpu_pda(cpu)->irq_spurious_count;
return sum;
}

u64 arch_irq_stat(void)
{
return atomic_read(&irq_err_count);
}

/*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
Expand Down
9 changes: 9 additions & 0 deletions fs/proc/proc_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ static const struct file_operations proc_vmalloc_operations = {
};
#endif

#ifndef arch_irq_stat_cpu
#define arch_irq_stat_cpu(cpu) 0
#endif
#ifndef arch_irq_stat
#define arch_irq_stat() 0
#endif

static int show_stat(struct seq_file *p, void *v)
{
int i;
Expand Down Expand Up @@ -509,7 +516,9 @@ static int show_stat(struct seq_file *p, void *v)
sum += temp;
per_irq_sum[j] += temp;
}
sum += arch_irq_stat_cpu(i);
}
sum += arch_irq_stat();

seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
(unsigned long long)cputime64_to_clock_t(user),
Expand Down
6 changes: 6 additions & 0 deletions include/asm-x86/hardirq.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
#else
# include "hardirq_64.h"
#endif

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

0 comments on commit a2eddfa

Please sign in to comment.