public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	linux@lists.openrisc.net
Cc: mark.rutland@arm.com, tony@atomide.com, catalin.marinas@arm.com,
	will.deacon@arm.com, Vladimir Murzin <vladimir.murzin@arm.com>,
	tglx@linutronix.de, jonas@southpole.se,
	lorenzo.pieralisi@arm.com, linux@arm.linux.org.uk,
	shc_work@mail.ru, khilman@linaro.org, jason@lakedaemon.net,
	marc.zyngier@arm.com, stefan.kristiansson@saunalahti.fi,
	larry.bassel@linaro.org, shawn.guo@freescale.com,
	baohua@kernel.org, sboyd@codeaurora.org, kernel@pengutronix.de,
	sudeep.holla@arm.com, schwidefsky@de.ibm.com,
	maxime.ripard@free-electrons.com, vkale@apm.com
Subject: [PATCH v2 01/26] genirq: add irq_domain-aware core IRQ handler
Date: Tue, 26 Aug 2014 11:03:16 +0100	[thread overview]
Message-ID: <1409047421-27649-2-git-send-email-marc.zyngier@arm.com> (raw)
In-Reply-To: <1409047421-27649-1-git-send-email-marc.zyngier@arm.com>

Calling irq_find_mapping from outside a irq_{enter,exit} section is
unsafe and produces ugly messages if CONFIG_PROVE_RCU is enabled:
If coming from the idle state, the rcu_read_lock call in irq_find_mapping
will generate an unpleasant warning:

<quote>
===============================
[ INFO: suspicious RCU usage. ]
3.16.0-rc1+ #135 Not tainted
-------------------------------
include/linux/rcupdate.h:871 rcu_read_lock() used illegally while idle!

other info that might help us debug this:

RCU used illegally from idle CPU!
rcu_scheduler_active = 1, debug_locks = 0
RCU used illegally from extended quiescent state!
1 lock held by swapper/0/0:
 #0:  (rcu_read_lock){......}, at: [<ffffffc00010206c>]
irq_find_mapping+0x4c/0x198
</quote>

As this issue is fairly widespread and involves at least three
different architectures, a possible solution is to add a new
handle_domain_irq entry point into the generic IRQ code that
the interrupt controller code can call.

This new function takes an irq_domain, and calls into irq_find_domain
inside the irq_{enter,exit} block. An additional "lookup" parameter is
used to allow non-domain architecture code to be replaced by this as well.

Interrupt controllers can then be updated to use the new mechanism.

This code is sitting behind a new CONFIG_HANDLE_DOMAIN_IRQ, as not all
architectures implement set_irq_regs (yes, mn10300, I'm looking at you...).

Reported-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 include/linux/irqdesc.h | 19 +++++++++++++++++++
 kernel/irq/Kconfig      |  3 +++
 kernel/irq/irqdesc.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 472c021..ff24667 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -12,6 +12,8 @@ struct irq_affinity_notify;
 struct proc_dir_entry;
 struct module;
 struct irq_desc;
+struct irq_domain;
+struct pt_regs;
 
 /**
  * struct irq_desc - interrupt descriptor
@@ -118,6 +120,23 @@ static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *de
 
 int generic_handle_irq(unsigned int irq);
 
+#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+/*
+ * Convert a HW interrupt number to a logical one using a IRQ domain,
+ * and handle the result interrupt number. Return -EINVAL if
+ * conversion failed. Providing a NULL domain indicates that the
+ * conversion has already been done.
+ */
+int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
+			bool lookup, struct pt_regs *regs);
+
+static inline int handle_domain_irq(struct irq_domain *domain,
+				    unsigned int hwirq, struct pt_regs *regs)
+{
+	return __handle_domain_irq(domain, hwirq, true, regs);
+}
+#endif
+
 /* Test to see if a driver has successfully requested an irq */
 static inline int irq_has_action(unsigned int irq)
 {
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index d269cec..225086b 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -55,6 +55,9 @@ config GENERIC_IRQ_CHIP
 config IRQ_DOMAIN
 	bool
 
+config HANDLE_DOMAIN_IRQ
+	bool
+
 config IRQ_DOMAIN_DEBUG
 	bool "Expose hardware/virtual IRQ mapping via debugfs"
 	depends on IRQ_DOMAIN && DEBUG_FS
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 1487a12..a1782f8 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -14,6 +14,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/radix-tree.h>
 #include <linux/bitmap.h>
+#include <linux/irqdomain.h>
 
 #include "internals.h"
 
@@ -336,6 +337,47 @@ int generic_handle_irq(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(generic_handle_irq);
 
+#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+/**
+ * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain
+ * @domain:	The domain where to perform the lookup
+ * @hwirq:	The HW irq number to convert to a logical one
+ * @lookup:	Whether to perform the domain lookup or not
+ * @regs:	Register file coming from the low-level handling code
+ *
+ * Returns:	0 on success, or -EINVAL if conversion has failed
+ */
+int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
+			bool lookup, struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+	unsigned int irq = hwirq;
+	int ret = 0;
+
+	irq_enter();
+
+#ifdef CONFIG_IRQ_DOMAIN
+	if (lookup)
+		irq = irq_find_mapping(domain, hwirq);
+#endif
+
+	/*
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
+	 */
+	if (unlikely(!irq || irq >= nr_irqs)) {
+		ack_bad_irq(irq);
+		ret = -EINVAL;
+	} else {
+		generic_handle_irq(irq);
+	}
+
+	irq_exit();
+	set_irq_regs(old_regs);
+	return ret;
+}
+#endif
+
 /* Dynamic interrupt handling */
 
 /**
-- 
2.0.4

  reply	other threads:[~2014-08-26 10:03 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-26 10:03 [PATCH v2 00/26] genirq: fix use of irq_find_mapping outside of legal RCU context Marc Zyngier
2014-08-26 10:03 ` Marc Zyngier [this message]
2014-08-26 17:42   ` [PATCH v2 01/26] genirq: add irq_domain-aware core IRQ handler Stephen Boyd
2014-08-26 18:07     ` Marc Zyngier
2014-08-26 18:46       ` Stephen Boyd
2014-08-26 19:05         ` Stephen Boyd
2014-09-01 15:22         ` Russell King - ARM Linux
2014-08-26 10:03 ` [PATCH v2 02/26] arm64: convert handle_IRQ to use __handle_domain_irq Marc Zyngier
2014-08-26 16:51   ` Catalin Marinas
2014-08-26 16:58     ` Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 03/26] ARM: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 04/26] openrisc: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 05/26] irqchip: GIC: convert to handle_domain_irq Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 06/26] irqchip: armada-370-xp: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 07/26] irqchip: clps711x: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 08/26] irqchip: mmp: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 09/26] irqchip: mxs: " Marc Zyngier
2014-08-27  6:38   ` Shawn Guo
2014-08-26 10:03 ` [PATCH v2 10/26] irqchip: orion: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 11/26] irqchip: s3c24xx: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 12/26] irqchip: sirfsoc: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 13/26] irqchip: sun4i: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 14/26] irqchip: versatile-fpga: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 15/26] irqchip: vic: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 16/26] irqchip: vt8500: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 17/26] irqchip: zevio: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 18/26] irqchip: GICv3: " Marc Zyngier
2014-08-26 10:03 ` [PATCH v2 19/26] irqchip: atmel-aic: " Marc Zyngier
2014-09-01  9:32   ` Nicolas Ferre
2014-09-01 10:16   ` Boris BREZILLON
2014-08-26 10:03 ` [PATCH v2 20/26] irqchip: atmel-aic5: " Marc Zyngier
2014-09-01  9:33   ` Nicolas Ferre
2014-09-01  9:51   ` Boris BREZILLON
2014-08-26 10:03 ` [PATCH v2 21/26] irqchip: or1k-pic: " Marc Zyngier
2014-08-27 17:09   ` Stefan Kristiansson
2014-08-26 10:03 ` [PATCH v2 22/26] ARM: imx: avic: " Marc Zyngier
2014-08-27  6:40   ` Shawn Guo
2014-08-26 10:03 ` [PATCH v2 23/26] ARM: imx: tzic: " Marc Zyngier
2014-08-27  6:40   ` Shawn Guo
2014-08-26 10:03 ` [PATCH v2 24/26] ARM: omap2: irq: " Marc Zyngier
2014-08-26 20:57   ` Tony Lindgren
2014-08-26 10:03 ` [PATCH v2 25/26] arm64: get rid of handle_IRQ Marc Zyngier
2014-08-26 16:53   ` Catalin Marinas
2014-08-26 10:03 ` [PATCH v2 26/26] openrisc: " Marc Zyngier
2014-08-26 21:34 ` [PATCH v2 00/26] genirq: fix use of irq_find_mapping outside of legal RCU context Thomas Gleixner
2014-08-27  9:33   ` Marc Zyngier
2014-09-03 12:04     ` Jason Cooper
2014-09-03 12:09       ` Thomas Gleixner
2014-09-03 12:21         ` Marc Zyngier
2014-09-03 12:25           ` Thomas Gleixner
2014-09-03 12:37             ` Jason Cooper
2014-09-03 12:40               ` Marc Zyngier
2014-09-03 12:37             ` Marc Zyngier
2014-09-03 13:18 ` Jason Cooper

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=1409047421-27649-2-git-send-email-marc.zyngier@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=baohua@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=jason@lakedaemon.net \
    --cc=jonas@southpole.se \
    --cc=kernel@pengutronix.de \
    --cc=khilman@linaro.org \
    --cc=larry.bassel@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=linux@lists.openrisc.net \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=sboyd@codeaurora.org \
    --cc=schwidefsky@de.ibm.com \
    --cc=shawn.guo@freescale.com \
    --cc=shc_work@mail.ru \
    --cc=stefan.kristiansson@saunalahti.fi \
    --cc=sudeep.holla@arm.com \
    --cc=tglx@linutronix.de \
    --cc=tony@atomide.com \
    --cc=vkale@apm.com \
    --cc=vladimir.murzin@arm.com \
    --cc=will.deacon@arm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox