ARM: SMP: provide individual IPI interrupt statistics
This separates out the individual IPI interrupt counts from the total IPI count, which allows better visibility of what IPIs are being used for. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
@@ -5,13 +5,15 @@
|
|||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
#define NR_IPI 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int __softirq_pending;
|
unsigned int __softirq_pending;
|
||||||
#ifdef CONFIG_LOCAL_TIMERS
|
#ifdef CONFIG_LOCAL_TIMERS
|
||||||
unsigned int local_timer_irqs;
|
unsigned int local_timer_irqs;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
unsigned int ipi_irqs;
|
unsigned int ipi_irqs[NR_IPI];
|
||||||
#endif
|
#endif
|
||||||
} ____cacheline_aligned irq_cpustat_t;
|
} ____cacheline_aligned irq_cpustat_t;
|
||||||
|
|
||||||
|
@@ -62,6 +62,11 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||||||
for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
|
for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
|
||||||
n *= 10;
|
n *= 10;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
if (prec < 4)
|
||||||
|
prec = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
char cpuname[12];
|
char cpuname[12];
|
||||||
|
|
||||||
|
@@ -382,16 +382,28 @@ void arch_send_call_function_single_ipi(int cpu)
|
|||||||
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
|
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *ipi_types[NR_IPI] = {
|
||||||
|
#define S(x,s) [x - IPI_TIMER] = s
|
||||||
|
S(IPI_TIMER, "Timer broadcast interrupts"),
|
||||||
|
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
|
||||||
|
S(IPI_CALL_FUNC, "Function call interrupts"),
|
||||||
|
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
|
||||||
|
S(IPI_CPU_STOP, "CPU stop interrupts"),
|
||||||
|
};
|
||||||
|
|
||||||
void show_ipi_list(struct seq_file *p, int prec)
|
void show_ipi_list(struct seq_file *p, int prec)
|
||||||
{
|
{
|
||||||
unsigned int cpu;
|
unsigned int cpu, i;
|
||||||
|
|
||||||
seq_printf(p, "%*s: ", prec, "IPI");
|
for (i = 0; i < NR_IPI; i++) {
|
||||||
|
seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
|
||||||
|
|
||||||
for_each_present_cpu(cpu)
|
for_each_present_cpu(cpu)
|
||||||
seq_printf(p, "%10u ", __get_irq_stat(cpu, ipi_irqs));
|
seq_printf(p, "%10u ",
|
||||||
|
__get_irq_stat(cpu, ipi_irqs[i]));
|
||||||
|
|
||||||
seq_printf(p, " Inter-processor interrupts\n");
|
seq_printf(p, " %s\n", ipi_types[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -506,7 +518,8 @@ asmlinkage void __exception do_IPI(int ipinr, struct pt_regs *regs)
|
|||||||
unsigned int cpu = smp_processor_id();
|
unsigned int cpu = smp_processor_id();
|
||||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
|
|
||||||
__inc_irq_stat(cpu, ipi_irqs);
|
if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
|
||||||
|
__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
|
||||||
|
|
||||||
switch (ipinr) {
|
switch (ipinr) {
|
||||||
case IPI_TIMER:
|
case IPI_TIMER:
|
||||||
|
Reference in New Issue
Block a user