[PATCH 2/2] PCI: rcar-host: Convert struct rcar_msi mask_lock into raw spinlock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The rcar_msi_irq_unmask() function may be called from a PCI driver
request_threaded_irq() function. This triggers kernel/irq/manage.c
__setup_irq() which locks raw spinlock &desc->lock descriptor lock
and with that descriptor lock held, calls rcar_msi_irq_unmask().

Since the &desc->lock descriptor lock is a raw spinlock , and the
rcar_msi .mask_lock is not a raw spinlock, this setup triggers
'BUG: Invalid wait context' with CONFIG_PROVE_RAW_LOCK_NESTING=y .

Use scoped_guard() to simplify the locking.

Fixes: 83ed8d4fa656 ("PCI: rcar: Convert to MSI domains")
Reported-by: Duy Nguyen <duy.nguyen.rh@xxxxxxxxxxx>
Reported-by: Thuan Nguyen <thuan.nguyen-hong@xxxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx>
---
=============================
[ BUG: Invalid wait context ]
6.17.0-rc4-next-20250905-00049-g13b74d3367a3-dirty #1117 Not tainted
-----------------------------
swapper/0/1 is trying to lock:
ffffff84c1974e58 (&msi->mask_lock){....}-{3:3}, at: rcar_msi_irq_unmask+0x28/0x70
other info that might help us debug this:
context-{5:5}
6 locks held by swapper/0/1:
 #0: ffffff84c0e0d0f8 (&dev->mutex){....}-{4:4}, at: device_lock+0x14/0x1c
 #1: ffffffc0817675b0 (pci_rescan_remove_lock){+.+.}-{4:4}, at: pci_lock_rescan_remove+0x18/0x20
 #2: ffffff84c2a691b0 (&dev->mutex){....}-{4:4}, at: device_lock+0x14/0x1c
 #3: ffffff84c1976108 (&dev->mutex){....}-{4:4}, at: device_lock+0x14/0x1c
 #4: ffffff84c2a71640 (&desc->request_mutex){+.+.}-{4:4}, at: __setup_irq+0xa4/0x5bc
 #5: ffffff84c2a714c8 (&irq_desc_lock_class){....}-{2:2}, at: __setup_irq+0x230/0x5bc
stack backtrace:
CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.17.0-rc4-next-20250905-00049-g13b74d3367a3-dirty #1117 PREEMPT
Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
Call trace:
 dump_backtrace+0x6c/0x7c (C)
 show_stack+0x14/0x1c
 dump_stack_lvl+0x68/0x8c
 dump_stack+0x14/0x1c
 __lock_acquire+0x3e8/0x1064
 lock_acquire+0x17c/0x2ac
 _raw_spin_lock_irqsave+0x54/0x70
 rcar_msi_irq_unmask+0x28/0x70
 irq_chip_unmask_parent+0x18/0x20
 cond_startup_parent+0x40/0x44
 pci_irq_startup_msi+0x20/0x58
 __irq_startup+0x34/0x84
 irq_startup+0x64/0x114
 __setup_irq+0x3f8/0x5bc
 request_threaded_irq+0x11c/0x148
 pcie_pme_probe+0xec/0x190
 pcie_port_probe_service+0x34/0x5c
 really_probe+0x190/0x350
 __driver_probe_device+0x120/0x138
 driver_probe_device+0x38/0xec
 __device_attach_driver+0x100/0x114
 bus_for_each_drv+0xa8/0xd0
 __device_attach+0xdc/0x15c
 device_initial_probe+0x10/0x18
 bus_probe_device+0x38/0xa0
 device_add+0x554/0x68c
 device_register+0x1c/0x28
 pcie_portdrv_probe+0x480/0x518
 pci_device_probe+0xcc/0x13c
 really_probe+0x190/0x350
 __driver_probe_device+0x120/0x138
 driver_probe_device+0x38/0xec
 __device_attach_driver+0x100/0x114
 bus_for_each_drv+0xa8/0xd0
 __device_attach+0xdc/0x15c
 device_initial_probe+0x10/0x18
 pci_bus_add_device+0xb8/0x130
 pci_bus_add_devices+0x50/0x74
 pci_host_probe+0x90/0xc4
 rcar_pcie_probe+0x5e8/0x650
 platform_probe+0x58/0x88
 really_probe+0x190/0x350
 __driver_probe_device+0x120/0x138
 driver_probe_device+0x38/0xec
 __driver_attach+0x158/0x168
 bus_for_each_dev+0x7c/0xd0
 driver_attach+0x20/0x28
 bus_add_driver+0xe0/0x1d8
 driver_register+0xac/0xe8
 __platform_driver_register+0x1c/0x24
 rcar_pcie_driver_init+0x18/0x20
 do_one_initcall+0xd4/0x220
 kernel_init_freeable+0x308/0x30c
 kernel_init+0x20/0x11c
 ret_from_fork+0x10/0x20
---
Cc: "Krzysztof Wilczyński" <kwilczynski@xxxxxxxxxx>
Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
Cc: Lorenzo Pieralisi <lpieralisi@xxxxxxxxxx>
Cc: Magnus Damm <magnus.damm@xxxxxxxxx>
Cc: Manivannan Sadhasivam <mani@xxxxxxxxxx>
Cc: Marc Zyngier <maz@xxxxxxxxxx>
Cc: Rob Herring <robh@xxxxxxxxxx>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx>
Cc: linux-pci@xxxxxxxxxxxxxxx
Cc: linux-renesas-soc@xxxxxxxxxxxxxxx
---
 drivers/pci/controller/pcie-rcar-host.c | 27 ++++++++++++-------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 625a00f3b2230..213028052aa58 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
@@ -38,7 +39,7 @@ struct rcar_msi {
 	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
 	struct irq_domain *domain;
 	struct mutex map_lock;
-	spinlock_t mask_lock;
+	raw_spinlock_t mask_lock;
 	int irq1;
 	int irq2;
 };
@@ -602,28 +603,26 @@ static void rcar_msi_irq_mask(struct irq_data *d)
 {
 	struct rcar_msi *msi = irq_data_get_irq_chip_data(d);
 	struct rcar_pcie *pcie = &msi_to_host(msi)->pcie;
-	unsigned long flags;
 	u32 value;
 
-	spin_lock_irqsave(&msi->mask_lock, flags);
-	value = rcar_pci_read_reg(pcie, PCIEMSIIER);
-	value &= ~BIT(d->hwirq);
-	rcar_pci_write_reg(pcie, value, PCIEMSIIER);
-	spin_unlock_irqrestore(&msi->mask_lock, flags);
+	scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) {
+		value = rcar_pci_read_reg(pcie, PCIEMSIIER);
+		value &= ~BIT(d->hwirq);
+		rcar_pci_write_reg(pcie, value, PCIEMSIIER);
+	}
 }
 
 static void rcar_msi_irq_unmask(struct irq_data *d)
 {
 	struct rcar_msi *msi = irq_data_get_irq_chip_data(d);
 	struct rcar_pcie *pcie = &msi_to_host(msi)->pcie;
-	unsigned long flags;
 	u32 value;
 
-	spin_lock_irqsave(&msi->mask_lock, flags);
-	value = rcar_pci_read_reg(pcie, PCIEMSIIER);
-	value |= BIT(d->hwirq);
-	rcar_pci_write_reg(pcie, value, PCIEMSIIER);
-	spin_unlock_irqrestore(&msi->mask_lock, flags);
+	scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) {
+		value = rcar_pci_read_reg(pcie, PCIEMSIIER);
+		value |= BIT(d->hwirq);
+		rcar_pci_write_reg(pcie, value, PCIEMSIIER);
+	}
 }
 
 static void rcar_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
@@ -736,7 +735,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
 	int err;
 
 	mutex_init(&msi->map_lock);
-	spin_lock_init(&msi->mask_lock);
+	raw_spin_lock_init(&msi->mask_lock);
 
 	err = of_address_to_resource(dev->of_node, 0, &res);
 	if (err)
-- 
2.51.0





[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux