LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH irqchip-next] genirq: Let cond_unmask_eoi_irq() issue an EOI for non-masked IRQs
@ 2021-08-12 22:21 Valentin Schneider
  0 siblings, 0 replies; only message in thread
From: Valentin Schneider @ 2021-08-12 22:21 UTC (permalink / raw)
  To: linux-kernel
  Cc: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi, Vincenzo Frascino

cond_unmask_eoi_irq() is invoked by the following flow handlers:

  handle_fasteoi_irq()
  handle_fasteoi_ack_irq()
  handle_fasteoi_mask_irq()
  handle_strict_flow_irq()

Unlike all the other handlers mentioned above, handle_strict_flow_irq()
is *not* guaranteed to have issued mask_irq() on a oneshot IRQ before
entering this function (it could be flow-masked instead).

If the primary handler of such an IRQ does not wake any threaded handler, we
will then fail to issue an EOI, which as per handle_strict_flow_irq() is a
big no-no.

Remove the check against irqd_irq_masked() in cond_unmask_eoi_irq(). The
handle_fasteoi_*() handlers remain unaffected as they unconditionally mask
oneshot IRQs, and handle_strict_flow_irq() will now issue an EOI for a
flow-masked IRQ which did not wake its thread.

Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
---
I was going through the stack again to refresh my memory when I found
this.

Force-threaded IRQs are unaffected as their primary handler is
irq_default_primary_handler() which unconditionally wakes the thread. Many
oneshot IRQs also have no primary handler, so they too get the
default. There *are* a handful out there with a primary handler that can
return something else than IRQ_WAKE_THREAD, so it does seem something we
wanna do.

If this needs a Fixes:, it would be:
32797fe1c8ee ("genirq: Don't mask IRQ within flow handler if IRQ is flow-masked")
---
 kernel/irq/chip.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 099bc7e13d1b..80d6291d355d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -686,13 +686,11 @@ static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
 		return;
 	}
 	/*
-	 * We need to unmask in the following cases:
-	 * - Oneshot irq which did not wake the thread (caused by a
-	 *   spurious interrupt or a primary handler handling it
-	 *   completely).
+	 * We need to EOI and potentially unmask in case the oneshot irq did not
+	 * wake the thread (caused by a spurious interrupt or a primary handler
+	 * handling it completely).
 	 */
-	if (!irqd_irq_disabled(&desc->irq_data) &&
-	    irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot) {
+	if (!irqd_irq_disabled(&desc->irq_data) && !desc->threads_oneshot) {
 		eoi_irq(desc);
 		unmask_irq(desc);
 	} else if (!(chip->flags & IRQCHIP_EOI_THREADED)) {
-- 
2.25.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-12 22:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 22:21 [PATCH irqchip-next] genirq: Let cond_unmask_eoi_irq() issue an EOI for non-masked IRQs Valentin Schneider

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).