Skip to content
/ linux Public

Commit d60ed85

Browse files
keithbuschSasha Levin
authored andcommitted
PCI: Fix pci_slot_lock () device locking
[ Upstream commit 1f5e57c ] Like pci_bus_lock(), pci_slot_lock() needs to lock the bridge device to prevent warnings like: pcieport 0000:e2:05.0: unlocked secondary bus reset via: pciehp_reset_slot+0x55/0xa0 Take and release the lock for the bridge providing the slot for the lock/trylock and unlock routines. Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Link: https://patch.msgid.link/20260130165953.751063-3-kbusch@meta.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent cad253d commit d60ed85

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

drivers/pci/pci.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5438,10 +5438,9 @@ static int pci_bus_trylock(struct pci_bus *bus)
54385438
/* Do any devices on or below this slot prevent a bus reset? */
54395439
static bool pci_slot_resettable(struct pci_slot *slot)
54405440
{
5441-
struct pci_dev *dev;
5441+
struct pci_dev *dev, *bridge = slot->bus->self;
54425442

5443-
if (slot->bus->self &&
5444-
(slot->bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
5443+
if (bridge && (bridge->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
54455444
return false;
54465445

54475446
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
@@ -5458,7 +5457,10 @@ static bool pci_slot_resettable(struct pci_slot *slot)
54585457
/* Lock devices from the top of the tree down */
54595458
static void pci_slot_lock(struct pci_slot *slot)
54605459
{
5461-
struct pci_dev *dev;
5460+
struct pci_dev *dev, *bridge = slot->bus->self;
5461+
5462+
if (bridge)
5463+
pci_dev_lock(bridge);
54625464

54635465
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
54645466
if (!dev->slot || dev->slot != slot)
@@ -5473,7 +5475,7 @@ static void pci_slot_lock(struct pci_slot *slot)
54735475
/* Unlock devices from the bottom of the tree up */
54745476
static void pci_slot_unlock(struct pci_slot *slot)
54755477
{
5476-
struct pci_dev *dev;
5478+
struct pci_dev *dev, *bridge = slot->bus->self;
54775479

54785480
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
54795481
if (!dev->slot || dev->slot != slot)
@@ -5483,12 +5485,18 @@ static void pci_slot_unlock(struct pci_slot *slot)
54835485
else
54845486
pci_dev_unlock(dev);
54855487
}
5488+
5489+
if (bridge)
5490+
pci_dev_unlock(bridge);
54865491
}
54875492

54885493
/* Return 1 on successful lock, 0 on contention */
54895494
static int pci_slot_trylock(struct pci_slot *slot)
54905495
{
5491-
struct pci_dev *dev;
5496+
struct pci_dev *dev, *bridge = slot->bus->self;
5497+
5498+
if (bridge && !pci_dev_trylock(bridge))
5499+
return 0;
54925500

54935501
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
54945502
if (!dev->slot || dev->slot != slot)
@@ -5513,6 +5521,9 @@ static int pci_slot_trylock(struct pci_slot *slot)
55135521
else
55145522
pci_dev_unlock(dev);
55155523
}
5524+
5525+
if (bridge)
5526+
pci_dev_unlock(bridge);
55165527
return 0;
55175528
}
55185529

0 commit comments

Comments
 (0)