From patchwork Thu Dec 10 19:18:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Grygorii Strashko X-Patchwork-Id: 7821821 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CB42ABEEE1 for ; Thu, 10 Dec 2015 19:19:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8278C203AD for ; Thu, 10 Dec 2015 19:19:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6F1F1205D8 for ; Thu, 10 Dec 2015 19:19:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752142AbbLJTT1 (ORCPT ); Thu, 10 Dec 2015 14:19:27 -0500 Received: from bear.ext.ti.com ([192.94.94.41]:57879 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750792AbbLJTTZ (ORCPT ); Thu, 10 Dec 2015 14:19:25 -0500 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id tBAJIOLY027983; Thu, 10 Dec 2015 13:18:24 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBAJINW5007979; Thu, 10 Dec 2015 13:18:23 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.224.2; Thu, 10 Dec 2015 13:18:23 -0600 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBAJIMPn030420; Thu, 10 Dec 2015 13:18:22 -0600 From: Grygorii Strashko To: Sebastian Andrzej Siewior , , Bjorn Helgaas CC: , , , , , , , , Grygorii Strashko , Kishon Vijay Abraham I , Jingoo Han , Kukjin Kim , Krzysztof Kozlowski , Richard Zhu , Lucas Stach , Thierry Reding , Stephen Warren , Alexandre Courbot , Simon Horman , Pratyush Anand , Michal Simek , =?UTF-8?q?S=C3=B6ren=20Brinkmann?= Subject: [PATCH v3] PCI: hosts: mark pcie/pci (msi) irq cascade handler as IRQF_NO_THREAD Date: Thu, 10 Dec 2015 21:18:20 +0200 Message-ID: <1449775100-30877-1-git-send-email-grygorii.strashko@ti.com> X-Mailer: git-send-email 2.6.4 MIME-Version: 1.0 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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: 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 requsted handler. generic_handle_irq grabs raw_locks and this needs to run in raw-irq context. This issue was originally reproduced on TI dra7-evem, but, as was identified during dicussion [1], other PCI(e) hosts can also suffer from this issue. So let's fix all them at once and mark pcie/pci (msi) irq cascade handlers IRQF_NO_THREAD explicitly. [1] https://lkml.org/lkml/2015/11/20/356 Cc: Kishon Vijay Abraham I Cc: Bjorn Helgaas Cc: Jingoo Han Cc: Kukjin Kim Cc: Krzysztof Kozlowski Cc: Richard Zhu Cc: Lucas Stach Cc: Thierry Reding Cc: Stephen Warren Cc: Alexandre Courbot Cc: Simon Horman Cc: Pratyush Anand Cc: Michal Simek Cc: "Sören Brinkmann" Cc: Sebastian Andrzej Siewior Signed-off-by: Grygorii Strashko Acked-by: Lucas Stach --- Changes in v3: - change applied to all affected pci(e) host drivers in drivers/pci/hosts. After some invsetigation I've decided to not touch arch code - it is not easy to identify all places which need to be fixed. if it's still required - i can send separate patches for arch/mips/pci/msi-octeon.c and arch/sparc/kernel/pci_msi.c. Links v2: https://lkml.org/lkml/2015/11/20/356 v1: https://lkml.org/lkml/2015/11/5/593 ref: https://lkml.org/lkml/2015/11/3/660 drivers/pci/host/pci-dra7xx.c | 13 ++++++++++++- 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 ++++-- drivers/pci/host/pcie-spear13xx.c | 3 ++- drivers/pci/host/pcie-xilinx.c | 3 ++- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 8c36880..0415192 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -301,8 +301,19 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, return -EINVAL; } + /* + * Mark dra7xx_pcie_msi IRQ as IRQF_NO_THREAD + * On -RT and if kernel is booting with "threadirqs" cmd line parameter + * the dra7xx_pcie_msi_irq_handler() will be forced threaded but, + * in the same time, it's IRQ dispatcher and calls generic_handle_irq(), + * which, in turn, will be resolved to handle_simple_irq() call. + * The handle_simple_irq() expected to be called with IRQ disabled, as + * result kernle will display warning: + * "irq XXX handler YYY+0x0/0x14 enabled interrupts". + */ ret = devm_request_irq(&pdev->dev, pp->irq, - dra7xx_pcie_msi_irq_handler, IRQF_SHARED, + dra7xx_pcie_msi_irq_handler, + IRQF_SHARED | IRQF_NO_THREAD, "dra7-pcie-msi", pp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index 01095e1..d997d22 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -522,7 +522,8 @@ static int __init exynos_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 22e8224..9ce7cd1 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -537,7 +537,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 ret; diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 3018ae5..3032311 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -1288,7 +1288,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 f4fa6c5..414c336 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -720,14 +720,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; diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index b95b756..a6cd823 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp, return -ENODEV; } ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler, - IRQF_SHARED, "spear1340-pcie", pp); + IRQF_SHARED | IRQF_NO_THREAD, + "spear1340-pcie", pp); if (ret) { dev_err(dev, "failed to request irq %d\n", pp->irq); return ret; diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index 3c7a0d5..4cfa463 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) port->irq = irq_of_parse_and_map(node, 0); err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler, - IRQF_SHARED, "xilinx-pcie", port); + IRQF_SHARED | IRQF_NO_THREAD, + "xilinx-pcie", port); if (err) { dev_err(dev, "unable to request irq %d\n", port->irq); return err;