Commit ac84c974 authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] protect 'action' in show_interrupts

Patch from Zwane Mwaikambo <zwane@linuxpower.ca>

On SMP or preemptible kernels, every instance of show_interrupts() is oopsily
racy wrt request_irq() and free_irq().

Fix that up by taking the irq_desc_t's lock while walking the action list.
parent f6da87ca
...@@ -515,6 +515,7 @@ show_interrupts(struct seq_file *p, void *v) ...@@ -515,6 +515,7 @@ show_interrupts(struct seq_file *p, void *v)
#endif #endif
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
seq_puts(p, " "); seq_puts(p, " ");
...@@ -525,9 +526,10 @@ show_interrupts(struct seq_file *p, void *v) ...@@ -525,9 +526,10 @@ show_interrupts(struct seq_file *p, void *v)
#endif #endif
for (i = 0; i < ACTUAL_NR_IRQS; i++) { for (i = 0; i < ACTUAL_NR_IRQS; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto unlock;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
...@@ -538,15 +540,18 @@ show_interrupts(struct seq_file *p, void *v) ...@@ -538,15 +540,18 @@ show_interrupts(struct seq_file *p, void *v)
#endif #endif
seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %c%s", seq_printf(p, " %c%s",
(action->flags & SA_INTERRUPT)?'+':' ', (action->flags & SA_INTERRUPT)?'+':' ',
action->name); action->name);
for (action=action->next; action; action = action->next) { for (action=action->next; action; action = action->next) {
seq_printf(p, ", %c%s", seq_printf(p, ", %c%s",
(action->flags & SA_INTERRUPT)?'+':' ', (action->flags & SA_INTERRUPT)?'+':' ',
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
#if CONFIG_SMP #if CONFIG_SMP
seq_puts(p, "IPI: "); seq_puts(p, "IPI: ");
......
...@@ -165,17 +165,22 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -165,17 +165,22 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_controller_lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto unlock;
seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
seq_printf(p, " %s", action->name); seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next) { for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
}
seq_putc(p, '\n'); seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_controller_lock, flags);
} }
#ifdef CONFIG_ARCH_ACORN #ifdef CONFIG_ARCH_ACORN
......
...@@ -228,11 +228,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -228,11 +228,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0; i < NR_IRQS; i++) { for (i = 0; i < NR_IRQS; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %10u %c %s", seq_printf(p, "%2d: %10u %c %s",
i, kstat_cpu(0).irqs[i], i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -243,6 +245,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -243,6 +245,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -135,6 +135,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -135,6 +135,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_printf(p, " "); seq_printf(p, " ");
for (j=0; j<NR_CPUS; j++) for (j=0; j<NR_CPUS; j++)
...@@ -143,9 +144,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -143,9 +144,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
...@@ -160,7 +162,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -160,7 +162,10 @@ int show_interrupts(struct seq_file *p, void *v)
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
seq_printf(p, "NMI: "); seq_printf(p, "NMI: ");
for (j = 0; j < NR_CPUS; j++) for (j = 0; j < NR_CPUS; j++)
......
...@@ -154,6 +154,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -154,6 +154,7 @@ int show_interrupts(struct seq_file *p, void *v)
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
irq_desc_t *idesc; irq_desc_t *idesc;
unsigned long flags;
seq_puts(p, " "); seq_puts(p, " ");
for (j=0; j<NR_CPUS; j++) for (j=0; j<NR_CPUS; j++)
...@@ -163,9 +164,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -163,9 +164,10 @@ int show_interrupts(struct seq_file *p, void *v)
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
idesc = irq_desc(i); idesc = irq_desc(i);
spin_lock_irqsave(&idesc->lock, flags);
action = idesc->action; action = idesc->action;
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
...@@ -176,10 +178,12 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -176,10 +178,12 @@ int show_interrupts(struct seq_file *p, void *v)
#endif #endif
seq_printf(p, " %14s", idesc->handler->typename); seq_printf(p, " %14s", idesc->handler->typename);
seq_printf(p, " %s", action->name); seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&idesc->lock, flags);
} }
seq_puts(p, "NMI: "); seq_puts(p, "NMI: ");
for (j = 0; j < NR_CPUS; j++) for (j = 0; j < NR_CPUS; j++)
......
...@@ -146,11 +146,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -146,11 +146,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < BAGET_IRQ_NR ; i++) { for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
i, kstat_cpu(0).irqs[i], i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -161,6 +163,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -161,6 +163,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -97,11 +97,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -97,11 +97,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction *action; struct irqaction *action;
unsigned long flags;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
i, kstat_cpu(0).irqs[i], i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -112,6 +114,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -112,6 +114,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -222,6 +222,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -222,6 +222,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_printf(p, " "); seq_printf(p, " ");
for (j=0; j<smp_num_cpus; j++) for (j=0; j<smp_num_cpus; j++)
...@@ -229,20 +230,25 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -229,20 +230,25 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if ( !action || !action->handler ) if ( !action || !action->handler )
continue; goto skip;
seq_printf(p, "%3d: ", i); seq_printf(p, "%3d: ", i);
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
if ( irq_desc[i].handler ) if ( irq_desc[i].handler )
seq_printf(p, " %s ", irq_desc[i].handler->typename ); seq_printf(p, " %s ", irq_desc[i].handler->typename );
else else
seq_puts(p, " None "); seq_puts(p, " None ");
seq_printf(p, " %s",action->name); seq_printf(p, " %s",action->name);
for (action=action->next; action; action = action->next) { for (action=action->next; action; action = action->next) {
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
seq_printf(p, "BAD: %10lu\n", spurious_count); seq_printf(p, "BAD: %10lu\n", spurious_count);
return 0; return 0;
...@@ -437,6 +443,7 @@ void __init init_IRQ(void) ...@@ -437,6 +443,7 @@ void __init init_IRQ(void)
irq_desc[i].action = 0; irq_desc[i].action = 0;
irq_desc[i].depth = 1; irq_desc[i].depth = 1;
irq_desc[i].handler = &it8172_irq_type; irq_desc[i].handler = &it8172_irq_type;
spin_lock_init(&irq_desc[i].lock);
} }
/* /*
......
...@@ -73,17 +73,19 @@ volatile unsigned long irq_err_count, spurious_count; ...@@ -73,17 +73,19 @@ volatile unsigned long irq_err_count, spurious_count;
int show_interrupts(struct seq_file *p, void *v) int show_interrupts(struct seq_file *p, void *v)
{ {
struct irqaction * action; struct irqaction * action;
unsigned long flags;
int i; int i;
seq_puts(p, " "); seq_puts(p, " ");
for (i=0; i < 1 /*smp_num_cpus*/; i++) for (i=0; i < 1 /*smp_num_cpus*/; i++)
seq_printf(p, "CPU%d ", i); seq_printf(p, "CPU%d ", i);
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto unlock;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %14s", irq_desc[i].handler->typename);
...@@ -92,6 +94,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -92,6 +94,8 @@ int show_interrupts(struct seq_file *p, void *v)
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
seq_printf(p, "ERR: %10lu\n", irq_err_count); seq_printf(p, "ERR: %10lu\n", irq_err_count);
return 0; return 0;
......
...@@ -128,11 +128,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -128,11 +128,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < 32 ; i++) { for (i = 0 ; i < 32 ; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
i, kstat_cpu(0).irqs[i], i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -143,6 +145,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -143,6 +145,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -99,11 +99,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -99,11 +99,13 @@ int show_interrupts(struct seq_file *p, void *v)
int i; int i;
int num = 0; int num = 0;
struct irqaction *action; struct irqaction *action;
unsigned long flags;
for (i = 0; i < ATLASINT_END; i++, num++) { for (i = 0; i < ATLASINT_END; i++, num++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -114,6 +116,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -114,6 +116,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_printf(p, " [hw0]\n"); seq_printf(p, " [hw0]\n");
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
return 0; return 0;
} }
...@@ -243,6 +247,7 @@ void __init init_IRQ(void) ...@@ -243,6 +247,7 @@ void __init init_IRQ(void)
irq_desc[i].action = 0; irq_desc[i].action = 0;
irq_desc[i].depth = 1; irq_desc[i].depth = 1;
irq_desc[i].handler = &atlas_irq_type; irq_desc[i].handler = &atlas_irq_type;
spin_lock_init(&irq_desc[i].lock);
} }
#ifdef CONFIG_REMOTE_DEBUG #ifdef CONFIG_REMOTE_DEBUG
......
...@@ -119,11 +119,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -119,11 +119,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction *action; struct irqaction *action;
unsigned long flags;
for (i = 0; i < NR_IRQS; i++) { for (i = 0; i < NR_IRQS; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
i, kstat_cpu(0).irqs[i], i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -134,6 +136,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -134,6 +136,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -95,11 +95,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -95,11 +95,13 @@ int show_interrupts(struct seq_file *p, void *v)
int i; int i;
int num = 0; int num = 0;
struct irqaction *action; struct irqaction *action;
unsigned long flags;
for (i = 0; i < ATLASINT_END; i++, num++) { for (i = 0; i < ATLASINT_END; i++, num++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto unlock;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -110,6 +112,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -110,6 +112,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_puts(p, " [hw0]\n"); seq_puts(p, " [hw0]\n");
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
return 0; return 0;
} }
...@@ -239,6 +243,7 @@ void __init init_IRQ(void) ...@@ -239,6 +243,7 @@ void __init init_IRQ(void)
irq_desc[i].action = 0; irq_desc[i].action = 0;
irq_desc[i].depth = 1; irq_desc[i].depth = 1;
irq_desc[i].handler = &atlas_irq_type; irq_desc[i].handler = &atlas_irq_type;
spin_lock_init(&irq_desc[i].lock);
} }
#ifdef CONFIG_REMOTE_DEBUG #ifdef CONFIG_REMOTE_DEBUG
......
...@@ -125,11 +125,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -125,11 +125,13 @@ int show_interrupts(struct seq_file *p, void *v)
int i; int i;
int num = 0; int num = 0;
struct irqaction *action; struct irqaction *action;
unsigned long flags;
for (i = 0; i < 8; i++, num++) { for (i = 0; i < 8; i++, num++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip_1;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -140,11 +142,14 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -140,11 +142,14 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_puts(p, " [on-chip]\n"); seq_puts(p, " [on-chip]\n");
skip_1:
local_irq_restore(flags);
} }
for (i = 0; i < MALTAINT_END; i++, num++) { for (i = 0; i < MALTAINT_END; i++, num++) {
local_irq_save(flags);
action = hw0_irq_action[i]; action = hw0_irq_action[i];
if (!action) if (!action)
continue; goto skip_2;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -155,6 +160,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -155,6 +160,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_puts(p, " [hw0]\n"); seq_puts(p, " [hw0]\n");
skip_2:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -237,11 +237,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -237,11 +237,13 @@ int show_interrupts(struct seq_file *p, void *v)
int i; int i;
int num = 0; int num = 0;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < 16 ; i++, num++) { for (i = 0 ; i < 16 ; i++, num++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip_1;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -252,11 +254,14 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -252,11 +254,14 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_puts(p, " [on-chip]\n"); seq_puts(p, " [on-chip]\n");
skip_1:
local_irq_restore(flags);
} }
for (i = 0 ; i < 24 ; i++, num++) { for (i = 0 ; i < 24 ; i++, num++) {
local_irq_save(flags);
action = local_irq_action[i]; action = local_irq_action[i];
if (!action) if (!action)
continue; goto skip_2;
seq_printf(p, "%2d: %8d %c %s", seq_printf(p, "%2d: %8d %c %s",
num, kstat_cpu(0).irqs[num], num, kstat_cpu(0).irqs[num],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
...@@ -267,6 +272,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -267,6 +272,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_puts(p, " [local]\n"); seq_puts(p, " [local]\n");
skip_2:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -141,11 +141,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -141,11 +141,13 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
local_irq_save(flags);
action = irq_action[i]; action = irq_action[i];
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ', (action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name); action->name);
...@@ -156,6 +158,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -156,6 +158,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -346,6 +346,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -346,6 +346,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_puts(p, " "); seq_puts(p, " ");
for (j=0; j<NR_CPUS; j++) for (j=0; j<NR_CPUS; j++)
...@@ -354,9 +355,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -354,9 +355,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if ( !action || !action->handler ) if ( !action || !action->handler )
continue; goto skip;
seq_printf(p, "%3d: ", i); seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
for (j = 0; j < NR_CPUS; j++) for (j = 0; j < NR_CPUS; j++)
...@@ -373,8 +375,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -373,8 +375,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
seq_printf(p, " %s", action->name); seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next) for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
#ifdef CONFIG_TAU_INT #ifdef CONFIG_TAU_INT
if (tau_initialized){ if (tau_initialized){
......
...@@ -341,6 +341,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -341,6 +341,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_printf(p, " "); seq_printf(p, " ");
for (j=0; j<NR_CPUS; j++) { for (j=0; j<NR_CPUS; j++) {
...@@ -350,9 +351,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -350,9 +351,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action || !action->handler) if (!action || !action->handler)
continue; goto skip;
seq_printf(p, "%3d: ", i); seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
for (j = 0; j < NR_CPUS; j++) { for (j = 0; j < NR_CPUS; j++) {
...@@ -371,6 +373,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -371,6 +373,8 @@ int show_interrupts(struct seq_file *p, void *v)
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
return 0; return 0;
......
...@@ -90,6 +90,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -90,6 +90,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_puts(p, " "); seq_puts(p, " ");
for (j=0; j<smp_num_cpus; j++) for (j=0; j<smp_num_cpus; j++)
...@@ -97,9 +98,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -97,9 +98,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) { for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto unlock;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %14s", irq_desc[i].handler->typename);
...@@ -108,6 +110,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -108,6 +110,8 @@ int show_interrupts(struct seq_file *p, void *v)
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
return 0; return 0;
} }
......
...@@ -104,6 +104,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -104,6 +104,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int j; int j;
#endif #endif
...@@ -114,9 +115,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -114,9 +115,10 @@ int show_interrupts(struct seq_file *p, void *v)
return show_sun4d_interrupts(p, v); return show_sun4d_interrupts(p, v);
} }
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
local_irq_save(flags);
action = *(i + irq_action); action = *(i + irq_action);
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%3d: ", i); seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
...@@ -136,6 +138,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -136,6 +138,8 @@ int show_interrupts(struct seq_file *p, void *v)
action->name); action->name);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
local_irq_restore(flags);
} }
return 0; return 0;
} }
......
...@@ -78,6 +78,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -78,6 +78,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_puts(p, " "); seq_puts(p, " ");
for (i=0; i < 1 /*smp_num_cpus*/; i++) for (i=0; i < 1 /*smp_num_cpus*/; i++)
...@@ -87,10 +88,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -87,10 +88,10 @@ int show_interrupts(struct seq_file *p, void *v)
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
int j, count, num; int j, count, num;
const char *type_name = irq_desc[i].handler->typename; const char *type_name = irq_desc[i].handler->typename;
spin_lock_irqsave(&irq_desc[j].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto skip;
count = 0; count = 0;
num = -1; num = -1;
...@@ -108,11 +109,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -108,11 +109,13 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, " %*s%d", 14 - prec, type_name, num); seq_printf(p, " %*s%d", 14 - prec, type_name, num);
} else } else
seq_printf(p, " %14s", type_name); seq_printf(p, " %14s", type_name);
seq_printf(p, " %s", action->name); seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[j].lock, flags);
} }
seq_printf(p, "ERR: %10lu\n", irq_err_count); seq_printf(p, "ERR: %10lu\n", irq_err_count);
return 0; return 0;
......
...@@ -135,6 +135,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -135,6 +135,7 @@ int show_interrupts(struct seq_file *p, void *v)
{ {
int i, j; int i, j;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
seq_printf(p, " "); seq_printf(p, " ");
for (j=0; j<NR_CPUS; j++) for (j=0; j<NR_CPUS; j++)
...@@ -143,9 +144,10 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -143,9 +144,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
for (i = 0 ; i < NR_IRQS ; i++) { for (i = 0 ; i < NR_IRQS ; i++) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action; action = irq_desc[i].action;
if (!action) if (!action)
continue; goto skip;
seq_printf(p, "%3d: ",i); seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
...@@ -156,11 +158,13 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -156,11 +158,13 @@ int show_interrupts(struct seq_file *p, void *v)
kstat_cpu(j).irqs[i]); kstat_cpu(j).irqs[i]);
#endif #endif
seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next) for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name); seq_printf(p, ", %s", action->name);
seq_putc(p, '\n'); seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} }
seq_printf(p, "NMI: "); seq_printf(p, "NMI: ");
for (j = 0; j < NR_CPUS; j++) for (j = 0; j < NR_CPUS; j++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment