linux/kernel/irq
Thomas Gleixner cc40a2916d genirq: Sanitize spurious interrupt detection of threaded irqs
commit 1e77d0a1ed upstream.

Till reported that the spurious interrupt detection of threaded
interrupts is broken in two ways:

- note_interrupt() is called for each action thread of a shared
  interrupt line. That's wrong as we are only interested whether none
  of the device drivers felt responsible for the interrupt, but by
  calling multiple times for a single interrupt line we account
  IRQ_NONE even if one of the drivers felt responsible.

- note_interrupt() when called from the thread handler is not
  serialized. That leaves the members of irq_desc which are used for
  the spurious detection unprotected.

To solve this we need to defer the spurious detection of a threaded
interrupt to the next hardware interrupt context where we have
implicit serialization.

If note_interrupt is called with action_ret == IRQ_WAKE_THREAD, we
check whether the previous interrupt requested a deferred check. If
not, we request a deferred check for the next hardware interrupt and
return.

If set, we check whether one of the interrupt threads signaled
success. Depending on this information we feed the result into the
spurious detector.

If one primary handler of a shared interrupt returns IRQ_HANDLED we
disable the deferred check of irq threads on the same line, as we have
found at least one device driver who cared.

Reported-by: Till Straumann <strauman@slac.stanford.edu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Austin Schuh <austin@peloton-tech.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: linux-can@vger.kernel.org
Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1303071450130.22263@ionos
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-06-30 20:12:00 -07:00
..
Kconfig genirq: Generic irq chip requires IRQ_DOMAIN 2014-02-05 10:17:32 +01:00
Makefile irq: add irq_domain translation infrastructure 2011-07-28 01:32:04 -06:00
autoprobe.c genirq: Handle pending irqs in irq_startup() 2012-02-15 11:56:59 +01:00
chip.c irq: Fix some trivial typos in comments 2013-10-18 14:49:30 +02:00
debug.h irq: hide debug macros so they don't collide with others. 2012-04-23 12:30:03 -04:00
devres.c genirq: Add devm_request_any_context_irq() 2014-02-09 15:27:21 +01:00
dummychip.c genirq: Export dummy_irq_chip 2012-08-21 16:14:23 +02:00
generic-chip.c Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2013-07-13 15:37:30 -07:00
handle.c random: make 'add_interrupt_randomness()' do something sane 2012-07-14 20:17:28 -04:00
internals.h genirq: Introduce irq_do_set_affinity() to reduce duplicated code 2012-05-24 22:36:40 +02:00
irqdesc.c genirq: Add missing irq_to_desc export for CONFIG_SPARSE_IRQ=n 2014-02-11 10:30:36 +01:00
irqdomain.c genirq: Include missing header file in irqdomain.c 2014-02-27 13:29:35 +01:00
manage.c genirq: Sanitize spurious interrupt detection of threaded irqs 2014-06-30 20:12:00 -07:00
migration.c genirq: Introduce irq_do_set_affinity() to reduce duplicated code 2012-05-24 22:36:40 +02:00
pm.c irq: Enable all irqs unconditionally in irq_resume 2013-11-25 22:20:02 +01:00
proc.c irqdomain: Include hwirq number in /proc/interrupts 2013-06-24 14:02:42 +01:00
resend.c genirq: Provide means to retrigger parent 2012-11-01 12:11:31 +01:00
settings.h genirq: Prevent spurious detection for unconditionally polled interrupts 2013-11-13 16:03:02 +01:00
spurious.c genirq: Sanitize spurious interrupt detection of threaded irqs 2014-06-30 20:12:00 -07:00