linux-stable/kernel/irq
Thomas Gleixner 528d3b767e genirq: Disable interrupts for force threaded handlers
commit 81e2073c17 upstream.

With interrupt force threading all device interrupt handlers are invoked
from kernel threads. Contrary to hard interrupt context the invocation only
disables bottom halfs, but not interrupts. This was an oversight back then
because any code like this will have an issue:

thread(irq_A)
  irq_handler(A)
    spin_lock(&foo->lock);

interrupt(irq_B)
  irq_handler(B)
    spin_lock(&foo->lock);

This has been triggered with networking (NAPI vs. hrtimers) and console
drivers where printk() happens from an interrupt which interrupted the
force threaded handler.

Now people noticed and started to change the spin_lock() in the handler to
spin_lock_irqsave() which affects performance or add IRQF_NOTHREAD to the
interrupt request which in turn breaks RT.

Fix the root cause and not the symptom and disable interrupts before
invoking the force threaded handler which preserves the regular semantics
and the usefulness of the interrupt force threading as a general debugging
tool.

For not RT this is not changing much, except that during the execution of
the threaded handler interrupts are delayed until the handler
returns. Vs. scheduling and softirq processing there is no difference.

For RT kernels there is no issue.

Fixes: 8d32a307e4 ("genirq: Provide forced interrupt threading")
Reported-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Johan Hovold <johan@kernel.org>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/20210317143859.513307808@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-24 10:59:26 +01:00
..
affinity.c genirq/affinity: Fix node generation from cpumask 2017-01-12 11:39:31 +01:00
autoprobe.c
chip.c genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() 2019-04-17 08:36:47 +02:00
cpuhotplug.c genirq: Make the cpuhotplug migration code less noisy 2015-10-22 14:34:57 +02:00
debug.h genirq: Guard handle_bad_irq log messages 2018-03-03 10:23:25 +01:00
devres.c
dummychip.c
generic-chip.c genirq/generic_chip: Verify irqs_per_chip <= 32 2016-09-02 20:20:59 +02:00
handle.c genirq: Add untracked irq handler 2016-06-18 10:00:55 +02:00
internals.h genirq: Avoid summation loops for /proc/stat 2019-04-05 22:29:12 +02:00
ipi.c genirq/ipi: Fixup checks against nr_cpu_ids 2017-08-24 17:12:21 -07:00
irqdesc.c genirq: Properly pair kobject_del() with kobject_add() 2019-09-06 10:19:39 +02:00
irqdomain.c irqdomain: Avoid activating interrupts more than once 2017-02-09 08:08:31 +01:00
Kconfig genirq: Let GENERIC_IRQ_IPI select IRQ_DOMAIN_HIERARCHY 2020-11-18 18:26:23 +01:00
Makefile genirq: Add a helper to spread an affinity mask for MSI/MSI-X vectors 2016-07-04 12:25:14 +02:00
manage.c genirq: Disable interrupts for force threaded handlers 2021-03-24 10:59:26 +01:00
migration.c genirq/generic_pending: Do not lose pending affinity update 2020-06-03 08:16:47 +02:00
msi.c genirq/msi: Add cpumask allocation to alloc_msi_entry 2016-09-14 22:11:08 +02:00
pm.c Merge branches 'irq-urgent-for-linus' and 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2015-11-15 09:30:48 -08:00
proc.c Merge branch 'irq/for-block' into irq/core 2016-07-04 12:26:05 +02:00
resend.c genirq: Prevent NULL pointer dereference in resend_irqs() 2019-09-21 07:14:04 +02:00
settings.h genirq: Add flag to force mask in disable_irq[_nosync]() 2015-10-11 11:33:42 +02:00
spurious.c genirq: Use a common macro to go through the actions list 2016-02-15 00:07:34 +01:00