diff mbox

[3.16.y-ckt,stable] Patch "PCI: host: Mark PCIe/PCI (MSI) IRQ cascade handlers as IRQF_NO_THREAD" has been added to the 3.16.y-ckt tree

Message ID 1454507939-29453-1-git-send-email-luis.henriques@canonical.com
State New
Headers show

Commit Message

Luis Henriques Feb. 3, 2016, 1:58 p.m. UTC
This is a note to let you know that I have just added a patch titled

    PCI: host: Mark PCIe/PCI (MSI) IRQ cascade handlers as IRQF_NO_THREAD

to the linux-3.16.y-queue branch of the 3.16.y-ckt extended stable tree 
which can be found at:

    http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.16.y-queue

This patch is scheduled to be released in version 3.16.7-ckt24.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.16.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

---8<------------------------------------------------------------

From 3d238df7b81dbd0d558e0badb0869f623e3095fb Mon Sep 17 00:00:00 2001
From: Grygorii Strashko <grygorii.strashko@ti.com>
Date: Thu, 10 Dec 2015 21:18:20 +0200
Subject: PCI: host: Mark PCIe/PCI (MSI) IRQ cascade handlers as IRQF_NO_THREAD
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

commit 8ff0ef996ca00028519c70e8d51d32bd37eb51dc upstream.

On -RT and if kernel is booting with "threadirqs" cmd line parameter,
PCIe/PCI (MSI) IRQ cascade handlers (like dra7xx_pcie_msi_irq_handler())
will be forced threaded and, as result, will generate warnings like this:

  WARNING: CPU: 1 PID: 82 at kernel/irq/handle.c:150 handle_irq_event_percpu+0x14c/0x174()
  irq 460 handler irq_default_primary_handler+0x0/0x14 enabled interrupts
  Backtrace:
   (warn_slowpath_common) from (warn_slowpath_fmt+0x38/0x40)
   (warn_slowpath_fmt) from (handle_irq_event_percpu+0x14c/0x174)
   (handle_irq_event_percpu) from (handle_irq_event+0x84/0xb8)
   (handle_irq_event) from (handle_simple_irq+0x90/0x118)
   (handle_simple_irq) from (generic_handle_irq+0x30/0x44)
   (generic_handle_irq) from (dra7xx_pcie_msi_irq_handler+0x7c/0x8c)
   (dra7xx_pcie_msi_irq_handler) from (irq_forced_thread_fn+0x28/0x5c)
   (irq_forced_thread_fn) from (irq_thread+0x128/0x204)

This happens because all of them invoke generic_handle_irq() from the
requested handler.  generic_handle_irq() grabs raw_locks and thus needs to
run in raw-IRQ context.

This issue was originally reproduced on TI dra7-evem, but, as was
identified during discussion [1], other hosts can also suffer from this
issue.  Fix all them at once by marking PCIe/PCI (MSI) IRQ cascade handlers
IRQF_NO_THREAD explicitly.

[1] http://lkml.kernel.org/r/1448027966-21610-1-git-send-email-grygorii.strashko@ti.com

[bhelgaas: add stable tag, fix typos]
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Lucas Stach <l.stach@pengutronix.de> (for imx6)
CC: Kishon Vijay Abraham I <kishon@ti.com>
CC: Jingoo Han <jingoohan1@gmail.com>
CC: Kukjin Kim <kgene@kernel.org>
CC: Krzysztof Kozlowski <k.kozlowski@samsung.com>
CC: Richard Zhu <Richard.Zhu@freescale.com>
CC: Thierry Reding <thierry.reding@gmail.com>
CC: Stephen Warren <swarren@wwwdotorg.org>
CC: Alexandre Courbot <gnurou@gmail.com>
CC: Simon Horman <horms@verge.net.au>
CC: Pratyush Anand <pratyush.anand@gmail.com>
CC: Michal Simek <michal.simek@xilinx.com>
CC: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
CC: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
[ luis: backported to 3.16:
  - dropped changes to pci-dra7xx.c, pcie-spear13xx.c, pcie-xilinx.c
  - adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/pci/host/pci-exynos.c | 3 ++-
 drivers/pci/host/pci-imx6.c   | 3 ++-
 drivers/pci/host/pci-tegra.c  | 2 +-
 drivers/pci/host/pcie-rcar.c  | 6 ++++--
 4 files changed, 9 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index c5d0ca384502..ab8bcaabaf21 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -535,7 +535,8 @@  static int __init add_pcie_port(struct pcie_port *pp,

 		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
 					exynos_pcie_msi_irq_handler,
-					IRQF_SHARED, "exynos-pcie", pp);
+					IRQF_SHARED | IRQF_NO_THREAD,
+					"exynos-pcie", pp);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request msi irq\n");
 			return ret;
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index a568efaa331c..72cd923e4ab3 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -497,7 +497,8 @@  static int __init imx6_add_pcie_port(struct pcie_port *pp,

 		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
 		                       imx6_pcie_msi_handler,
-		                       IRQF_SHARED, "mx6-pcie-msi", pp);
+				       IRQF_SHARED | IRQF_NO_THREAD,
+				       "mx6-pcie-msi", pp);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request MSI irq\n");
 			return -ENODEV;
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 083cf37ca047..0407b1d6bab8 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1280,7 +1280,7 @@  static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)

 	msi->irq = err;

-	err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
+	err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
 			  tegra_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index f7d3de32c9a0..b5b0d683bb2d 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -712,14 +712,16 @@  static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)

 	/* Two irqs are for MSI, but they are also used for non-MSI irqs */
 	err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
-			       IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       rcar_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
 		goto err;
 	}

 	err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
-			       IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
+			       IRQF_SHARED | IRQF_NO_THREAD,
+			       rcar_msi_irq_chip.name, pcie);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
 		goto err;