aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2014-07-22 10:58:52 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-07-28 04:02:36 -0400
commite2213e04c1b1e44a09a9d05b79809b7e63c9217e (patch)
tree9b049b184a56d4f635caeaf85edf28df39459d90 /arch/s390
parentdc295880c6752076f8b94ba3885d0bfff09e3e82 (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.c95
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);
30EXPORT_PER_CPU_SYMBOL_GPL(irq_stat); 30EXPORT_PER_CPU_SYMBOL_GPL(irq_stat);
31 31
32struct irq_class { 32struct 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 */
47static const struct irq_class irqclass_main_desc[NR_IRQS_BASE] = { 48static 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 */
58static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { 59static 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
93void __init init_IRQ(void) 94void __init init_IRQ(void)
@@ -116,33 +117,37 @@ void do_IRQ(struct pt_regs *regs, int irq)
116 */ 117 */
117int show_interrupts(struct seq_file *p, void *v) 118int 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 }
148out: 153out: