From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Marc Zyngier <marc.zyngier@arm.com>,
Robert Hodaszi <Robert.Hodaszi@digi.com>
Subject: [patch V2 1/6] genirq: Delay deactivation in free_irq()
Date: Fri, 28 Jun 2019 13:11:49 +0200 [thread overview]
Message-ID: <20190628111440.098196390@linutronix.de> (raw)
In-Reply-To: 20190628111148.828731433@linutronix.de
When interrupts are shutdown, they are immediately deactivated in the
irqdomain hierarchy. While this looks obviously correct there is a subtle
issue:
There might be an interrupt in flight when free_irq() is invoking the
shutdown. This is properly handled at the irq descriptor / primary handler
level, but the deactivation might completely disable resources which are
required to acknowledge the interrupt.
Split the shutdown code and deactivate the interrupt after synchronization
in free_irq(). Fixup all other usage sites where this is not an issue to
invoke the combined shutdown_and_deactivate() function instead.
This still might be an issue if the interrupt in flight servicing is
delayed on a remote CPU beyond the invocation of synchronize_irq(), but
that cannot be handled at that level and needs to be handled in the
synchronize_irq() context.
Fixes: f8264e34965a ("irqdomain: Introduce new interfaces to support hierarchy irqdomains")
Reported-by: Robert Hodaszi <Robert.Hodaszi@digi.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
---
V2: Fix comment and add Reviewed tag
---
kernel/irq/autoprobe.c | 6 +++---
kernel/irq/chip.c | 6 ++++++
kernel/irq/cpuhotplug.c | 2 +-
kernel/irq/internals.h | 1 +
kernel/irq/manage.c | 12 +++++++++++-
5 files changed, 22 insertions(+), 5 deletions(-)
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -90,7 +90,7 @@ unsigned long probe_irq_on(void)
/* It triggered already - consider it spurious. */
if (!(desc->istate & IRQS_WAITING)) {
desc->istate &= ~IRQS_AUTODETECT;
- irq_shutdown(desc);
+ irq_shutdown_and_deactivate(desc);
} else
if (i < 32)
mask |= 1 << i;
@@ -127,7 +127,7 @@ unsigned int probe_irq_mask(unsigned lon
mask |= 1 << i;
desc->istate &= ~IRQS_AUTODETECT;
- irq_shutdown(desc);
+ irq_shutdown_and_deactivate(desc);
}
raw_spin_unlock_irq(&desc->lock);
}
@@ -169,7 +169,7 @@ int probe_irq_off(unsigned long val)
nr_of_irqs++;
}
desc->istate &= ~IRQS_AUTODETECT;
- irq_shutdown(desc);
+ irq_shutdown_and_deactivate(desc);
}
raw_spin_unlock_irq(&desc->lock);
}
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -314,6 +314,12 @@ void irq_shutdown(struct irq_desc *desc)
}
irq_state_clr_started(desc);
}
+}
+
+
+void irq_shutdown_and_deactivate(struct irq_desc *desc)
+{
+ irq_shutdown(desc);
/*
* This must be called even if the interrupt was never started up,
* because the activation can happen before the interrupt is
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -116,7 +116,7 @@ static bool migrate_one_irq(struct irq_d
*/
if (irqd_affinity_is_managed(d)) {
irqd_set_managed_shutdown(d);
- irq_shutdown(desc);
+ irq_shutdown_and_deactivate(desc);
return false;
}
affinity = cpu_online_mask;
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -82,6 +82,7 @@ extern int irq_activate_and_startup(stru
extern int irq_startup(struct irq_desc *desc, bool resend, bool force);
extern void irq_shutdown(struct irq_desc *desc);
+extern void irq_shutdown_and_deactivate(struct irq_desc *desc);
extern void irq_enable(struct irq_desc *desc);
extern void irq_disable(struct irq_desc *desc);
extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu);
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/sched/rt.h>
@@ -1699,6 +1700,7 @@ static struct irqaction *__free_irq(stru
/* If this was the last handler, shut down the IRQ line: */
if (!desc->action) {
irq_settings_clr_disable_unlazy(desc);
+ /* Only shutdown. Deactivate after synchronize_hardirq() */
irq_shutdown(desc);
}
@@ -1768,6 +1770,14 @@ static struct irqaction *__free_irq(stru
* require it to deallocate resources over the slow bus.
*/
chip_bus_lock(desc);
+ /*
+ * There is no interrupt on the fly anymore. Deactivate it
+ * completely.
+ */
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ irq_domain_deactivate_irq(&desc->irq_data);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+
irq_release_resources(desc);
chip_bus_sync_unlock(desc);
irq_remove_timings(desc);
@@ -1855,7 +1865,7 @@ static const void *__cleanup_nmi(unsigne
}
irq_settings_clr_disable_unlazy(desc);
- irq_shutdown(desc);
+ irq_shutdown_and_deactivate(desc);
irq_release_resources(desc);
next prev parent reply other threads:[~2019-06-28 11:21 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-28 11:11 [patch V2 0/6] x86/irq: Cure various interrupt issues Thomas Gleixner
2019-06-28 11:11 ` Thomas Gleixner [this message]
2019-07-03 8:16 ` [tip:x86/apic] genirq: Delay deactivation in free_irq() tip-bot for Thomas Gleixner
2019-06-28 11:11 ` [patch V2 2/6] genirq: Fix misleading synchronize_irq() documentation Thomas Gleixner
2019-07-01 14:53 ` Peter Zijlstra
2019-07-01 18:01 ` Thomas Gleixner
2019-07-01 18:23 ` Peter Zijlstra
2019-07-03 8:16 ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-06-28 11:11 ` [patch V2 3/6] genirq: Add optional hardware synchronization for shutdown Thomas Gleixner
2019-07-01 8:48 ` Marc Zyngier
2019-07-01 14:56 ` Peter Zijlstra
2019-07-01 18:02 ` Thomas Gleixner
2019-07-03 8:17 ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-06-28 11:11 ` [patch V2 4/6] x86/ioapic: Implement irq_get_irqchip_state() callback Thomas Gleixner
2019-07-03 8:18 ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-06-28 11:11 ` [patch V2 5/6] x86/irq: Handle spurious interrupt after shutdown gracefully Thomas Gleixner
2019-07-03 8:18 ` [tip:x86/apic] " tip-bot for Thomas Gleixner
2019-06-28 11:11 ` [patch V2 6/6] x86/irq: Seperate unused system vectors from spurious entry again Thomas Gleixner
2019-07-03 8:19 ` [tip:x86/apic] " tip-bot for Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190628111440.098196390@linutronix.de \
--to=tglx@linutronix.de \
--cc=Robert.Hodaszi@digi.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.