forked from luck/tmp_suning_uos_patched
genirq: Prevent irq storm on migration
move_native_irq() masks and unmasks the interrupt line unconditionally, but the interrupt line might be masked due to a threaded oneshot handler in progress. Unmasking the line in that case can lead to interrupt storms. Observed on PREEMPT_RT. Originally-from: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@kernel.org
This commit is contained in:
parent
afe8a88755
commit
f1a06390d0
|
@ -56,6 +56,7 @@ void move_masked_irq(int irq)
|
|||
void move_native_irq(int irq)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
bool masked;
|
||||
|
||||
if (likely(!(desc->status & IRQ_MOVE_PENDING)))
|
||||
return;
|
||||
|
@ -63,8 +64,15 @@ void move_native_irq(int irq)
|
|||
if (unlikely(desc->status & IRQ_DISABLED))
|
||||
return;
|
||||
|
||||
desc->irq_data.chip->irq_mask(&desc->irq_data);
|
||||
/*
|
||||
* Be careful vs. already masked interrupts. If this is a
|
||||
* threaded interrupt with ONESHOT set, we can end up with an
|
||||
* interrupt storm.
|
||||
*/
|
||||
masked = desc->status & IRQ_MASKED;
|
||||
if (!masked)
|
||||
desc->irq_data.chip->irq_mask(&desc->irq_data);
|
||||
move_masked_irq(irq);
|
||||
desc->irq_data.chip->irq_unmask(&desc->irq_data);
|
||||
if (!masked)
|
||||
desc->irq_data.chip->irq_unmask(&desc->irq_data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user