diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2014-07-22 10:58:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-07-28 04:02:36 -0400 |
commit | e2213e04c1b1e44a09a9d05b79809b7e63c9217e (patch) | |
tree | 9b049b184a56d4f635caeaf85edf28df39459d90 /arch/s390 | |
parent | dc295880c6752076f8b94ba3885d0bfff09e3e82 (diff) |
s390/irq: improve displayed interrupt order in /proc/interrupts
Rework the irqclass_main_desc and irqclass_sub_desc data structures which
are used to report detaild IRQ statistics in /proc/interrupts. When
called from the procfs ops, the entries in the structures are processed
one by one.
The index of an IRQ in the structures is identical to its definition in
the "enum interruption_class". To control and (re)order the displayed
sequence, introduce an irq member in each entry. This helps to display
related IRQs together without changing the assigned number in the
interruption_class enumeration. That means, adding and displaying new
IRQs are independent.
Finally, this new behavior improves to maintain a kernel ABI.
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/irq.c | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 99b0b09646ca..8eb82443cfbd 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
@@ -30,6 +30,7 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); | |||
30 | EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); | 30 | EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); |
31 | 31 | ||
32 | struct irq_class { | 32 | struct irq_class { |
33 | int irq; | ||
33 | char *name; | 34 | char *name; |
34 | char *desc; | 35 | char *desc; |
35 | }; | 36 | }; |
@@ -45,9 +46,9 @@ struct irq_class { | |||
45 | * up with having a sum which accounts each interrupt twice. | 46 | * up with having a sum which accounts each interrupt twice. |
46 | */ | 47 | */ |
47 | static const struct irq_class irqclass_main_desc[NR_IRQS_BASE] = { | 48 | static const struct irq_class irqclass_main_desc[NR_IRQS_BASE] = { |
48 | [EXT_INTERRUPT] = {.name = "EXT"}, | 49 | {.irq = EXT_INTERRUPT, .name = "EXT"}, |
49 | [IO_INTERRUPT] = {.name = "I/O"}, | 50 | {.irq = IO_INTERRUPT, .name = "I/O"}, |
50 | [THIN_INTERRUPT] = {.name = "AIO"}, | 51 | {.irq = THIN_INTERRUPT, .name = "AIO"}, |
51 | }; | 52 | }; |
52 | 53 | ||
53 | /* | 54 | /* |
@@ -56,38 +57,38 @@ static const struct irq_class irqclass_main_desc[NR_IRQS_BASE] = { | |||
56 | * In addition this list contains non external / I/O events like NMIs. | 57 | * In addition this list contains non external / I/O events like NMIs. |
57 | */ | 58 | */ |
58 | static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { | 59 | static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { |
59 | [IRQEXT_CLK] = {.name = "CLK", .desc = "[EXT] Clock Comparator"}, | 60 | {.irq = IRQEXT_CLK, .name = "CLK", .desc = "[EXT] Clock Comparator"}, |
60 | [IRQEXT_EXC] = {.name = "EXC", .desc = "[EXT] External Call"}, | 61 | {.irq = IRQEXT_EXC, .name = "EXC", .desc = "[EXT] External Call"}, |
61 | [IRQEXT_EMS] = {.name = "EMS", .desc = "[EXT] Emergency Signal"}, | 62 | {.irq = IRQEXT_EMS, .name = "EMS", .desc = "[EXT] Emergency Signal"}, |
62 | [IRQEXT_TMR] = {.name = "TMR", .desc = "[EXT] CPU Timer"}, | 63 | {.irq = IRQEXT_TMR, .name = "TMR", .desc = "[EXT] CPU Timer"}, |
63 | [IRQEXT_TLA] = {.name = "TAL", .desc = "[EXT] Timing Alert"}, | 64 | {.irq = IRQEXT_TLA, .name = "TAL", .desc = "[EXT] Timing Alert"}, |
64 | [IRQEXT_PFL] = {.name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, | 65 | {.irq = IRQEXT_PFL, .name = "PFL", .desc = "[EXT] Pseudo Page Fault"}, |
65 | [IRQEXT_DSD] = {.name = "DSD", .desc = "[EXT] DASD Diag"}, | 66 | {.irq = IRQEXT_DSD, .name = "DSD", .desc = "[EXT] DASD Diag"}, |
66 | [IRQEXT_VRT] = {.name = "VRT", .desc = "[EXT] Virtio"}, | 67 | {.irq = IRQEXT_VRT, .name = "VRT", .desc = "[EXT] Virtio"}, |
67 | [IRQEXT_SCP] = {.name = "SCP", .desc = "[EXT] Service Call"}, | 68 | {.irq = IRQEXT_SCP, .name = "SCP", .desc = "[EXT] Service Call"}, |
68 | [IRQEXT_IUC] = {.name = "IUC", .desc = "[EXT] IUCV"}, | 69 | {.irq = IRQEXT_IUC, .name = "IUC", .desc = "[EXT] IUCV"}, |
69 | [IRQEXT_CMS] = {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, | 70 | {.irq = IRQEXT_CMS, .name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"}, |
70 | [IRQEXT_CMC] = {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, | 71 | {.irq = IRQEXT_CMC, .name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"}, |
71 | [IRQEXT_CMR] = {.name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, | 72 | {.irq = IRQEXT_CMR, .name = "CMR", .desc = "[EXT] CPU-Measurement: RI"}, |
72 | [IRQIO_CIO] = {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, | 73 | {.irq = IRQIO_CIO, .name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"}, |
73 | [IRQIO_QAI] = {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, | 74 | {.irq = IRQIO_QAI, .name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"}, |
74 | [IRQIO_DAS] = {.name = "DAS", .desc = "[I/O] DASD"}, | 75 | {.irq = IRQIO_DAS, .name = "DAS", .desc = "[I/O] DASD"}, |
75 | [IRQIO_C15] = {.name = "C15", .desc = "[I/O] 3215"}, | 76 | {.irq = IRQIO_C15, .name = "C15", .desc = "[I/O] 3215"}, |
76 | [IRQIO_C70] = {.name = "C70", .desc = "[I/O] 3270"}, | 77 | {.irq = IRQIO_C70, .name = "C70", .desc = "[I/O] 3270"}, |
77 | [IRQIO_TAP] = {.name = "TAP", .desc = "[I/O] Tape"}, | 78 | {.irq = IRQIO_TAP, .name = "TAP", .desc = "[I/O] Tape"}, |
78 | [IRQIO_VMR] = {.name = "VMR", .desc = "[I/O] Unit Record Devices"}, | 79 | {.irq = IRQIO_VMR, .name = "VMR", .desc = "[I/O] Unit Record Devices"}, |
79 | [IRQIO_LCS] = {.name = "LCS", .desc = "[I/O] LCS"}, | 80 | {.irq = IRQIO_LCS, .name = "LCS", .desc = "[I/O] LCS"}, |
80 | [IRQIO_CLW] = {.name = "CLW", .desc = "[I/O] CLAW"}, | 81 | {.irq = IRQIO_CLW, .name = "CLW", .desc = "[I/O] CLAW"}, |
81 | [IRQIO_CTC] = {.name = "CTC", .desc = "[I/O] CTC"}, | 82 | {.irq = IRQIO_CTC, .name = "CTC", .desc = "[I/O] CTC"}, |
82 | [IRQIO_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, | 83 | {.irq = IRQIO_APB, .name = "APB", .desc = "[I/O] AP Bus"}, |
83 | [IRQIO_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, | 84 | {.irq = IRQIO_ADM, .name = "ADM", .desc = "[I/O] EADM Subchannel"}, |
84 | [IRQIO_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, | 85 | {.irq = IRQIO_CSC, .name = "CSC", .desc = "[I/O] CHSC Subchannel"}, |
85 | [IRQIO_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, | 86 | {.irq = IRQIO_PCI, .name = "PCI", .desc = "[I/O] PCI Interrupt" }, |
86 | [IRQIO_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, | 87 | {.irq = IRQIO_MSI, .name = "MSI", .desc = "[I/O] MSI Interrupt" }, |
87 | [IRQIO_VIR] = {.name = "VIR", .desc = "[I/O] Virtual I/O Devices"}, | 88 | {.irq = IRQIO_VIR, .name = "VIR", .desc = "[I/O] Virtual I/O Devices"}, |
88 | [IRQIO_VAI] = {.name = "VAI", .desc = "[I/O] Virtual I/O Devices AI"}, | 89 | {.irq = IRQIO_VAI, .name = "VAI", .desc = "[I/O] Virtual I/O Devices AI"}, |
89 | [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"}, | 90 | {.irq = NMI_NMI, .name = "NMI", .desc = "[NMI] Machine Check"}, |
90 | [CPU_RST] = {.name = "RST", .desc = "[CPU] CPU Restart"}, | 91 | {.irq = CPU_RST, .name = "RST", .desc = "[CPU] CPU Restart"}, |
91 | }; | 92 | }; |
92 | 93 | ||
93 | void __init init_IRQ(void) | 94 | void __init init_IRQ(void) |
@@ -116,33 +117,37 @@ void do_IRQ(struct pt_regs *regs, int irq) | |||
116 | */ | 117 | */ |
117 | int show_interrupts(struct seq_file *p, void *v) | 118 | int show_interrupts(struct seq_file *p, void *v) |
118 | { | 119 | { |
119 | int irq = *(loff_t *) v; | 120 | int index = *(loff_t *) v; |
120 | int cpu; | 121 | int cpu, irq; |
121 | 122 | ||
122 | get_online_cpus(); | 123 | get_online_cpus(); |
123 | if (irq == 0) { | 124 | if (index == 0) { |
124 | seq_puts(p, " "); | 125 | seq_puts(p, " "); |
125 | for_each_online_cpu(cpu) | 126 | for_each_online_cpu(cpu) |
126 | seq_printf(p, "CPU%d ", cpu); | 127 | seq_printf(p, "CPU%d ", cpu); |
127 | seq_putc(p, '\n'); | 128 | seq_putc(p, '\n'); |
128 | goto out; | 129 | goto out; |
129 | } | 130 | } |
130 | if (irq < NR_IRQS) { | 131 | if (index < NR_IRQS) { |
131 | if (irq >= NR_IRQS_BASE) | 132 | if (index >= NR_IRQS_BASE) |
132 | goto out; | 133 | goto out; |
133 | seq_printf(p, "%s: ", irqclass_main_desc[irq].name); | 134 | /* Adjust index to process irqclass_main_desc array entries */ |
135 | index--; | ||
136 | seq_printf(p, "%s: ", irqclass_main_desc[index].name); | ||
137 | irq = irqclass_main_desc[index].irq; | ||
134 | for_each_online_cpu(cpu) | 138 | for_each_online_cpu(cpu) |
135 | seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); | 139 | seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); |
136 | seq_putc(p, '\n'); | 140 | seq_putc(p, '\n'); |
137 | goto out; | 141 | goto out; |
138 | } | 142 | } |
139 | for (irq = 0; irq < NR_ARCH_IRQS; irq++) { | 143 | for (index = 0; index < NR_ARCH_IRQS; index++) { |
140 | seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); | 144 | seq_printf(p, "%s: ", irqclass_sub_desc[index].name); |
145 | irq = irqclass_sub_desc[index].irq; | ||
141 | for_each_online_cpu(cpu) | 146 | for_each_online_cpu(cpu) |
142 | seq_printf(p, "%10u ", | 147 | seq_printf(p, "%10u ", |
143 | per_cpu(irq_stat, cpu).irqs[irq]); | 148 | per_cpu(irq_stat, cpu).irqs[irq]); |
144 | if (irqclass_sub_desc[irq].desc) | 149 | if (irqclass_sub_desc[index].desc) |
145 | seq_printf(p, " %s", irqclass_sub_desc[irq].desc); | 150 | seq_printf(p, " %s", irqclass_sub_desc[index].desc); |
146 | seq_putc(p, '\n'); | 151 | seq_putc(p, '\n'); |
147 | } | 152 | } |
148 | out: | 153 | out: |