aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2013-05-06 15:20:26 -0400
committerHelge Deller <deller@gmx.de>2013-05-07 16:39:22 -0400
commitcd85d5514d5c4d7e78abac923fc032457d0c5091 (patch)
treeb8a9ce478be624481fa8ec7341dd0ab96e7fb7ca /arch/parisc/kernel
parent200c880420a2c02a0899120ce52d801fad705b90 (diff)
parisc: more irq statistics in /proc/interrupts
Add framework and initial values for more fine grained statistics in /proc/interrupts. Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/irq.c48
-rw-r--r--arch/parisc/kernel/smp.c3
2 files changed, 49 insertions, 2 deletions
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 810f9cf89e48..a237e32ede19 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -152,6 +152,40 @@ static struct irq_chip cpu_interrupt_type = {
152 .irq_retrigger = NULL, 152 .irq_retrigger = NULL,
153}; 153};
154 154
155DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
156#define irq_stats(x) (&per_cpu(irq_stat, x))
157
158/*
159 * /proc/interrupts printing for arch specific interrupts
160 */
161int arch_show_interrupts(struct seq_file *p, int prec)
162{
163 int j;
164
165#ifdef CONFIG_DEBUG_STACKOVERFLOW
166 seq_printf(p, "%*s: ", prec, "STK");
167 for_each_online_cpu(j)
168 seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage);
169 seq_printf(p, " Kernel stack usage\n");
170#endif
171#ifdef CONFIG_SMP
172 seq_printf(p, "%*s: ", prec, "RES");
173 for_each_online_cpu(j)
174 seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
175 seq_printf(p, " Rescheduling interrupts\n");
176 seq_printf(p, "%*s: ", prec, "CAL");
177 for_each_online_cpu(j)
178 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
179 irq_stats(j)->irq_tlb_count);
180 seq_printf(p, " Function call interrupts\n");
181 seq_printf(p, "%*s: ", prec, "TLB");
182 for_each_online_cpu(j)
183 seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
184 seq_printf(p, " TLB shootdowns\n");
185#endif
186 return 0;
187}
188
155int show_interrupts(struct seq_file *p, void *v) 189int show_interrupts(struct seq_file *p, void *v)
156{ 190{
157 int i = *(loff_t *) v, j; 191 int i = *(loff_t *) v, j;
@@ -219,6 +253,9 @@ int show_interrupts(struct seq_file *p, void *v)
219 raw_spin_unlock_irqrestore(&desc->lock, flags); 253 raw_spin_unlock_irqrestore(&desc->lock, flags);
220 } 254 }
221 255
256 if (i == NR_IRQS)
257 arch_show_interrupts(p, 3);
258
222 return 0; 259 return 0;
223} 260}
224 261
@@ -340,13 +377,22 @@ static inline void stack_overflow_check(struct pt_regs *regs)
340 /* Our stack starts directly behind the thread_info struct. */ 377 /* Our stack starts directly behind the thread_info struct. */
341 unsigned long stack_start = (unsigned long) current_thread_info(); 378 unsigned long stack_start = (unsigned long) current_thread_info();
342 unsigned long sp = regs->gr[30]; 379 unsigned long sp = regs->gr[30];
380 unsigned long stack_usage;
381 unsigned int *last_usage;
343 382
344 /* if sr7 != 0, we interrupted a userspace process which we do not want 383 /* if sr7 != 0, we interrupted a userspace process which we do not want
345 * to check for stack overflow. We will only check the kernel stack. */ 384 * to check for stack overflow. We will only check the kernel stack. */
346 if (regs->sr[7]) 385 if (regs->sr[7])
347 return; 386 return;
348 387
349 if (likely((sp - stack_start) < (THREAD_SIZE - STACK_MARGIN))) 388 /* calculate kernel stack usage */
389 stack_usage = sp - stack_start;
390 last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id());
391
392 if (unlikely(stack_usage > *last_usage))
393 *last_usage = stack_usage;
394
395 if (likely(stack_usage < (THREAD_SIZE - STACK_MARGIN)))
350 return; 396 return;
351 397
352 pr_emerg("stackcheck: %s will most likely overflow kernel stack " 398 pr_emerg("stackcheck: %s will most likely overflow kernel stack "
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index fd1bb1519c2b..218e20bff9d2 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -127,7 +127,7 @@ ipi_interrupt(int irq, void *dev_id)
127 unsigned long flags; 127 unsigned long flags;
128 128
129 /* Count this now; we may make a call that never returns. */ 129 /* Count this now; we may make a call that never returns. */
130 p->ipi_count++; 130 inc_irq_stat(irq_call_count);
131 131
132 mb(); /* Order interrupt and bit testing. */ 132 mb(); /* Order interrupt and bit testing. */
133 133
@@ -155,6 +155,7 @@ ipi_interrupt(int irq, void *dev_id)
155 155
156 case IPI_RESCHEDULE: 156 case IPI_RESCHEDULE:
157 smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); 157 smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
158 inc_irq_stat(irq_resched_count);
158 scheduler_ipi(); 159 scheduler_ipi();
159 break; 160 break;
160 161