diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2011-01-05 06:47:28 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-01-05 06:47:25 -0500 |
commit | 052ff461c8427629aee887ccc27478fc7373237c (patch) | |
tree | 1b2cae2956cc94c5b32730d467e20ff447b8c072 | |
parent | 545b288dcbdea58a2ce2afba5f6a8302d31ac459 (diff) |
[S390] irq: have detailed statistics for interrupt types
Up to now /proc/interrupts only has statistics for external and i/o
interrupts but doesn't split up them any further.
This patch adds a line for every single interrupt source so that it
is possible to easier tell what the machine is/was doing.
Part of the output now looks like this;
CPU0 CPU2 CPU4
EXT: 3898 4232 2305
I/O: 782 315 245
CLK: 1029 1964 727 [EXT] Clock Comparator
IPI: 2868 2267 1577 [EXT] Signal Processor
TMR: 0 0 0 [EXT] CPU Timer
TAL: 0 0 0 [EXT] Timing Alert
PFL: 0 0 0 [EXT] Pseudo Page Fault
[...]
NMI: 0 1 1 [NMI] Machine Checks
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/irq.h | 23 | ||||
-rw-r--r-- | arch/s390/kernel/irq.c | 30 | ||||
-rw-r--r-- | arch/s390/kernel/nmi.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 1 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 6 | ||||
-rw-r--r-- | drivers/s390/kvm/kvm_virtio.c | 3 | ||||
-rw-r--r-- | net/iucv/iucv.c | 2 |
11 files changed, 56 insertions, 20 deletions
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 7da991a858f8..f65faf63ab3a 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h | |||
@@ -1,23 +1,22 @@ | |||
1 | #ifndef _ASM_IRQ_H | 1 | #ifndef _ASM_IRQ_H |
2 | #define _ASM_IRQ_H | 2 | #define _ASM_IRQ_H |
3 | 3 | ||
4 | #ifdef __KERNEL__ | ||
5 | #include <linux/hardirq.h> | 4 | #include <linux/hardirq.h> |
6 | 5 | ||
7 | /* | ||
8 | * the definition of irqs has changed in 2.5.46: | ||
9 | * NR_IRQS is no longer the number of i/o | ||
10 | * interrupts (65536), but rather the number | ||
11 | * of interrupt classes (2). | ||
12 | * Only external and i/o interrupts make much sense here (CH). | ||
13 | */ | ||
14 | |||
15 | enum interruption_class { | 6 | enum interruption_class { |
16 | EXTERNAL_INTERRUPT, | 7 | EXTERNAL_INTERRUPT, |
17 | IO_INTERRUPT, | 8 | IO_INTERRUPT, |
18 | 9 | EXTINT_CLK, | |
10 | EXTINT_IPI, | ||
11 | EXTINT_TMR, | ||
12 | EXTINT_TLA, | ||
13 | EXTINT_PFL, | ||
14 | EXTINT_DSD, | ||
15 | EXTINT_VRT, | ||
16 | EXTINT_SCP, | ||
17 | EXTINT_IUC, | ||
18 | NMI_NMI, | ||
19 | NR_IRQS, | 19 | NR_IRQS, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | #endif /* __KERNEL__ */ | 22 | #endif /* _ASM_IRQ_H */ |
23 | #endif | ||
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 026a37a94fc9..9bd049b8f997 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
@@ -1,7 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/s390/kernel/irq.c | 2 | * Copyright IBM Corp. 2004,2010 |
3 | * | ||
4 | * Copyright IBM Corp. 2004,2007 | ||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 3 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
6 | * Thomas Spatzier (tspat@de.ibm.com) | 4 | * Thomas Spatzier (tspat@de.ibm.com) |
7 | * | 5 | * |
@@ -17,12 +15,31 @@ | |||
17 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
18 | #include <linux/profile.h> | 16 | #include <linux/profile.h> |
19 | 17 | ||
18 | struct irq_class { | ||
19 | char *name; | ||
20 | char *desc; | ||
21 | }; | ||
22 | |||
23 | static const struct irq_class intrclass_names[] = { | ||
24 | {.name = "EXT" }, | ||
25 | {.name = "I/O" }, | ||
26 | {.name = "CLK", .desc = "[EXT] Clock Comparator" }, | ||
27 | {.name = "IPI", .desc = "[EXT] Signal Processor" }, | ||
28 | {.name = "TMR", .desc = "[EXT] CPU Timer" }, | ||
29 | {.name = "TAL", .desc = "[EXT] Timing Alert" }, | ||
30 | {.name = "PFL", .desc = "[EXT] Pseudo Page Fault" }, | ||
31 | {.name = "DSD", .desc = "[EXT] DASD Diag" }, | ||
32 | {.name = "VRT", .desc = "[EXT] Virtio" }, | ||
33 | {.name = "SCP", .desc = "[EXT] Service Call" }, | ||
34 | {.name = "IUC", .desc = "[EXT] IUCV" }, | ||
35 | {.name = "NMI", .desc = "[NMI] Machine Check" }, | ||
36 | }; | ||
37 | |||
20 | /* | 38 | /* |
21 | * show_interrupts is needed by /proc/interrupts. | 39 | * show_interrupts is needed by /proc/interrupts. |
22 | */ | 40 | */ |
23 | int show_interrupts(struct seq_file *p, void *v) | 41 | int show_interrupts(struct seq_file *p, void *v) |
24 | { | 42 | { |
25 | static const char *intrclass_names[] = { "EXT", "I/O", }; | ||
26 | int i = *(loff_t *) v, j; | 43 | int i = *(loff_t *) v, j; |
27 | 44 | ||
28 | get_online_cpus(); | 45 | get_online_cpus(); |
@@ -34,15 +51,16 @@ int show_interrupts(struct seq_file *p, void *v) | |||
34 | } | 51 | } |
35 | 52 | ||
36 | if (i < NR_IRQS) { | 53 | if (i < NR_IRQS) { |
37 | seq_printf(p, "%s: ", intrclass_names[i]); | 54 | seq_printf(p, "%s: ", intrclass_names[i].name); |
38 | #ifndef CONFIG_SMP | 55 | #ifndef CONFIG_SMP |
39 | seq_printf(p, "%10u ", kstat_irqs(i)); | 56 | seq_printf(p, "%10u ", kstat_irqs(i)); |
40 | #else | 57 | #else |
41 | for_each_online_cpu(j) | 58 | for_each_online_cpu(j) |
42 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 59 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
43 | #endif | 60 | #endif |
61 | if (intrclass_names[i].desc) | ||
62 | seq_printf(p, " %s", intrclass_names[i].desc); | ||
44 | seq_putc(p, '\n'); | 63 | seq_putc(p, '\n'); |
45 | |||
46 | } | 64 | } |
47 | put_online_cpus(); | 65 | put_online_cpus(); |
48 | return 0; | 66 | return 0; |
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 1995c1712fc8..fab88431a06f 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Heiko Carstens <heiko.carstens@de.ibm.com>, | 8 | * Heiko Carstens <heiko.carstens@de.ibm.com>, |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/kernel_stat.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
13 | #include <linux/hardirq.h> | 14 | #include <linux/hardirq.h> |
@@ -255,7 +256,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs) | |||
255 | nmi_enter(); | 256 | nmi_enter(); |
256 | s390_idle_check(regs, S390_lowcore.mcck_clock, | 257 | s390_idle_check(regs, S390_lowcore.mcck_clock, |
257 | S390_lowcore.mcck_enter_timer); | 258 | S390_lowcore.mcck_enter_timer); |
258 | 259 | kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++; | |
259 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | 260 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; |
260 | mcck = &__get_cpu_var(cpu_mcck); | 261 | mcck = &__get_cpu_var(cpu_mcck); |
261 | umode = user_mode(regs); | 262 | umode = user_mode(regs); |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 94cf510b8fe1..a9702df22f3a 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -161,6 +161,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code, | |||
161 | { | 161 | { |
162 | unsigned long bits; | 162 | unsigned long bits; |
163 | 163 | ||
164 | kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++; | ||
164 | /* | 165 | /* |
165 | * handle bit signal external calls | 166 | * handle bit signal external calls |
166 | * | 167 | * |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 4c9d72d2e273..9e7b039458da 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #define KMSG_COMPONENT "time" | 15 | #define KMSG_COMPONENT "time" |
16 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 16 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
17 | 17 | ||
18 | #include <linux/kernel_stat.h> | ||
18 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
@@ -160,6 +161,7 @@ static void clock_comparator_interrupt(unsigned int ext_int_code, | |||
160 | unsigned int param32, | 161 | unsigned int param32, |
161 | unsigned long param64) | 162 | unsigned long param64) |
162 | { | 163 | { |
164 | kstat_cpu(smp_processor_id()).irqs[EXTINT_CLK]++; | ||
163 | if (S390_lowcore.clock_comparator == -1ULL) | 165 | if (S390_lowcore.clock_comparator == -1ULL) |
164 | set_clock_comparator(S390_lowcore.clock_comparator); | 166 | set_clock_comparator(S390_lowcore.clock_comparator); |
165 | } | 167 | } |
@@ -170,6 +172,7 @@ static void stp_timing_alert(struct stp_irq_parm *); | |||
170 | static void timing_alert_interrupt(unsigned int ext_int_code, | 172 | static void timing_alert_interrupt(unsigned int ext_int_code, |
171 | unsigned int param32, unsigned long param64) | 173 | unsigned int param32, unsigned long param64) |
172 | { | 174 | { |
175 | kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++; | ||
173 | if (param32 & 0x00c40000) | 176 | if (param32 & 0x00c40000) |
174 | etr_timing_alert((struct etr_irq_parm *) ¶m32); | 177 | etr_timing_alert((struct etr_irq_parm *) ¶m32); |
175 | if (param32 & 0x00038000) | 178 | if (param32 & 0x00038000) |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 8636dd00e393..1ccdf4d8aa85 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -324,6 +324,7 @@ static void do_cpu_timer_interrupt(unsigned int ext_int_code, | |||
324 | struct list_head cb_list; /* the callback queue */ | 324 | struct list_head cb_list; /* the callback queue */ |
325 | __u64 elapsed, next; | 325 | __u64 elapsed, next; |
326 | 326 | ||
327 | kstat_cpu(smp_processor_id()).irqs[EXTINT_TMR]++; | ||
327 | INIT_LIST_HEAD(&cb_list); | 328 | INIT_LIST_HEAD(&cb_list); |
328 | vq = &__get_cpu_var(virt_cpu_timer); | 329 | vq = &__get_cpu_var(virt_cpu_timer); |
329 | 330 | ||
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index fe5701e9efbf..839b16df72b3 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Copyright (C) 1995 Linus Torvalds | 10 | * Copyright (C) 1995 Linus Torvalds |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel_stat.h> | ||
13 | #include <linux/perf_event.h> | 14 | #include <linux/perf_event.h> |
14 | #include <linux/signal.h> | 15 | #include <linux/signal.h> |
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
@@ -543,6 +544,7 @@ static void pfault_interrupt(unsigned int ext_int_code, | |||
543 | struct task_struct *tsk; | 544 | struct task_struct *tsk; |
544 | __u16 subcode; | 545 | __u16 subcode; |
545 | 546 | ||
547 | kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; | ||
546 | /* | 548 | /* |
547 | * Get the external interruption subcode & pfault | 549 | * Get the external interruption subcode & pfault |
548 | * initial/completion signal bit. VM stores this | 550 | * initial/completion signal bit. VM stores this |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 266b34b55403..a3a5db58df18 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #define KMSG_COMPONENT "dasd" | 11 | #define KMSG_COMPONENT "dasd" |
12 | 12 | ||
13 | #include <linux/kernel_stat.h> | ||
13 | #include <linux/stddef.h> | 14 | #include <linux/stddef.h> |
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -238,6 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code, | |||
238 | addr_t ip; | 239 | addr_t ip; |
239 | int rc; | 240 | int rc; |
240 | 241 | ||
242 | kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; | ||
241 | switch (ext_int_code >> 24) { | 243 | switch (ext_int_code >> 24) { |
242 | case DASD_DIAG_CODE_31BIT: | 244 | case DASD_DIAG_CODE_31BIT: |
243 | ip = (addr_t) param32; | 245 | ip = (addr_t) param32; |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 35cc4686b99b..e65572e504ba 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel_stat.h> | ||
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/err.h> | 12 | #include <linux/err.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
@@ -18,8 +19,9 @@ | |||
18 | #include <linux/suspend.h> | 19 | #include <linux/suspend.h> |
19 | #include <linux/completion.h> | 20 | #include <linux/completion.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <asm/types.h> | ||
22 | #include <asm/s390_ext.h> | 22 | #include <asm/s390_ext.h> |
23 | #include <asm/types.h> | ||
24 | #include <asm/irq.h> | ||
23 | 25 | ||
24 | #include "sclp.h" | 26 | #include "sclp.h" |
25 | 27 | ||
@@ -402,6 +404,7 @@ static void sclp_interrupt_handler(unsigned int ext_int_code, | |||
402 | u32 finished_sccb; | 404 | u32 finished_sccb; |
403 | u32 evbuf_pending; | 405 | u32 evbuf_pending; |
404 | 406 | ||
407 | kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; | ||
405 | spin_lock(&sclp_lock); | 408 | spin_lock(&sclp_lock); |
406 | finished_sccb = param32 & 0xfffffff8; | 409 | finished_sccb = param32 & 0xfffffff8; |
407 | evbuf_pending = param32 & 0x3; | 410 | evbuf_pending = param32 & 0x3; |
@@ -824,6 +827,7 @@ static void sclp_check_handler(unsigned int ext_int_code, | |||
824 | { | 827 | { |
825 | u32 finished_sccb; | 828 | u32 finished_sccb; |
826 | 829 | ||
830 | kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; | ||
827 | finished_sccb = param32 & 0xfffffff8; | 831 | finished_sccb = param32 & 0xfffffff8; |
828 | /* Is this the interrupt we are waiting for? */ | 832 | /* Is this the interrupt we are waiting for? */ |
829 | if (finished_sccb == 0) | 833 | if (finished_sccb == 0) |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 375aeeaf9ea5..414427d64a8f 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> | 10 | * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel_stat.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/bootmem.h> | 15 | #include <linux/bootmem.h> |
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
@@ -25,6 +26,7 @@ | |||
25 | #include <asm/kvm_virtio.h> | 26 | #include <asm/kvm_virtio.h> |
26 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
27 | #include <asm/s390_ext.h> | 28 | #include <asm/s390_ext.h> |
29 | #include <asm/irq.h> | ||
28 | 30 | ||
29 | #define VIRTIO_SUBCODE_64 0x0D00 | 31 | #define VIRTIO_SUBCODE_64 0x0D00 |
30 | 32 | ||
@@ -379,6 +381,7 @@ static void kvm_extint_handler(unsigned int ext_int_code, | |||
379 | u16 subcode; | 381 | u16 subcode; |
380 | u32 param; | 382 | u32 param; |
381 | 383 | ||
384 | kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; | ||
382 | subcode = ext_int_code >> 16; | 385 | subcode = ext_int_code >> 16; |
383 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) | 386 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) |
384 | return; | 387 | return; |
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index f7db676de77d..1ee5dab3cfae 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #define KMSG_COMPONENT "iucv" | 36 | #define KMSG_COMPONENT "iucv" |
37 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 37 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
38 | 38 | ||
39 | #include <linux/kernel_stat.h> | ||
39 | #include <linux/module.h> | 40 | #include <linux/module.h> |
40 | #include <linux/moduleparam.h> | 41 | #include <linux/moduleparam.h> |
41 | #include <linux/spinlock.h> | 42 | #include <linux/spinlock.h> |
@@ -1804,6 +1805,7 @@ static void iucv_external_interrupt(unsigned int ext_int_code, | |||
1804 | struct iucv_irq_data *p; | 1805 | struct iucv_irq_data *p; |
1805 | struct iucv_irq_list *work; | 1806 | struct iucv_irq_list *work; |
1806 | 1807 | ||
1808 | kstat_cpu(smp_processor_id()).irqs[EXTINT_IUC]++; | ||
1807 | p = iucv_irq_data[smp_processor_id()]; | 1809 | p = iucv_irq_data[smp_processor_id()]; |
1808 | if (p->ippathid >= iucv_max_pathid) { | 1810 | if (p->ippathid >= iucv_max_pathid) { |
1809 | WARN_ON(p->ippathid >= iucv_max_pathid); | 1811 | WARN_ON(p->ippathid >= iucv_max_pathid); |