genirq: spurious: Run only one poller at a time
No point in running concurrent pollers which confuse each other by setting PENDING. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Родитель
c7259cd7af
Коммит
d05c65fff0
|
@ -21,6 +21,8 @@ static int irqfixup __read_mostly;
|
||||||
#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
|
#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
|
||||||
static void poll_spurious_irqs(unsigned long dummy);
|
static void poll_spurious_irqs(unsigned long dummy);
|
||||||
static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
|
static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
|
||||||
|
static int irq_poll_cpu;
|
||||||
|
static atomic_t irq_poll_active;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recovery handler for misrouted interrupts.
|
* Recovery handler for misrouted interrupts.
|
||||||
|
@ -92,6 +94,11 @@ static int misrouted_irq(int irq)
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
int i, ok = 0;
|
int i, ok = 0;
|
||||||
|
|
||||||
|
if (atomic_inc_return(&irq_poll_active) == 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
irq_poll_cpu = smp_processor_id();
|
||||||
|
|
||||||
for_each_irq_desc(i, desc) {
|
for_each_irq_desc(i, desc) {
|
||||||
if (!i)
|
if (!i)
|
||||||
continue;
|
continue;
|
||||||
|
@ -102,6 +109,8 @@ static int misrouted_irq(int irq)
|
||||||
if (try_one_irq(i, desc, false))
|
if (try_one_irq(i, desc, false))
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
atomic_dec(&irq_poll_active);
|
||||||
/* So the caller can adjust the irq error counts */
|
/* So the caller can adjust the irq error counts */
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
@ -111,6 +120,10 @@ static void poll_spurious_irqs(unsigned long dummy)
|
||||||
struct irq_desc *desc;
|
struct irq_desc *desc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (atomic_inc_return(&irq_poll_active) != 1)
|
||||||
|
goto out;
|
||||||
|
irq_poll_cpu = smp_processor_id();
|
||||||
|
|
||||||
for_each_irq_desc(i, desc) {
|
for_each_irq_desc(i, desc) {
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
|
@ -127,7 +140,8 @@ static void poll_spurious_irqs(unsigned long dummy)
|
||||||
try_one_irq(i, desc, true);
|
try_one_irq(i, desc, true);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
atomic_dec(&irq_poll_active);
|
||||||
mod_timer(&poll_spurious_irq_timer,
|
mod_timer(&poll_spurious_irq_timer,
|
||||||
jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
|
jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче