From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lucas Stach Date: Thu, 07 Jan 2016 09:18:16 +0000 Subject: Re: [PATCH v3] PCI: hosts: mark pcie/pci (msi) irq cascade handler as IRQF_NO_THREAD Message-Id: <1452158296.21272.15.camel@pengutronix.de> List-Id: References: <1449775100-30877-1-git-send-email-grygorii.strashko@ti.com> In-Reply-To: <1449775100-30877-1-git-send-email-grygorii.strashko@ti.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: linux-arm-kernel@lists.infradead.org Am Donnerstag, den 10.12.2015, 21:18 +0200 schrieb Grygorii Strashko: > 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: >=20 > WARNING: CPU: 1 PID: 82 at kernel/irq/handle.c:150 handle_irq_event_percp= u+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/0x1= 74) > (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+0x= 28/0x5c) > (irq_forced_thread_fn) from [] (irq_thread+0x128/0x204) >=20 > 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. >=20 > 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. >=20 > [1] https://lkml.org/lkml/2015/11/20/356 >=20 > 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=C3=B6ren Brinkmann" > Cc: Sebastian Andrzej Siewior > Signed-off-by: Grygorii Strashko Sorry this fell through the cracks, so here is my late Acked-by: Lucas Stach for the imx6 part. > --- > Changes in v3: > - change applied to all affected pci(e) host drivers in drivers/pci/host= s. > After some invsetigation I've decided to not touch arch code - it is n= ot easy > to identify all places which need to be fixed.=20 > if it's still required - i can send separate patches for=20 > 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 >=20 > 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(-) >=20 > 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; > } > =20 > + /* > + * 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 =3D 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_po= rt *pp, > =20 > ret =3D 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, > =20 > ret =3D 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) > =20 > msi->irq =3D err; > =20 > - err =3D request_irq(msi->irq, tegra_pcie_msi_irq, 0, > + err =3D 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 *p= cie) > =20 > /* Two irqs are for MSI, but they are also used for non-MSI irqs */ > err =3D 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; > } > =20 > err =3D 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-sp= ear13xx.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 =3D 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-xilin= x.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_po= rt *port) > =20 > port->irq =3D irq_of_parse_and_map(node, 0); > err =3D 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; --=20 Pengutronix e.K. | Lucas Stach | Industrial Linux Solutions | http://www.pengutronix.de/ |