Skip to content
/ linux Public

Commit d2f321c

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 7611479 commit d2f321c

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
@@ -5657,10 +5657,9 @@ static int pci_bus_trylock(struct pci_bus *bus)
56575657
/* Do any devices on or below this slot prevent a bus reset? */
56585658
static bool pci_slot_resetable(struct pci_slot *slot)
56595659
{
5660-
struct pci_dev *dev;
5660+
struct pci_dev *dev, *bridge = slot->bus->self;
56615661

5662-
if (slot->bus->self &&
5663-
(slot->bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
5662+
if (bridge && (bridge->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
56645663
return false;
56655664

56665665
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
@@ -5677,7 +5676,10 @@ static bool pci_slot_resetable(struct pci_slot *slot)
56775676
/* Lock devices from the top of the tree down */
56785677
static void pci_slot_lock(struct pci_slot *slot)
56795678
{
5680-
struct pci_dev *dev;
5679+
struct pci_dev *dev, *bridge = slot->bus->self;
5680+
5681+
if (bridge)
5682+
pci_dev_lock(bridge);
56815683

56825684
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
56835685
if (!dev->slot || dev->slot != slot)
@@ -5692,7 +5694,7 @@ static void pci_slot_lock(struct pci_slot *slot)
56925694
/* Unlock devices from the bottom of the tree up */
56935695
static void pci_slot_unlock(struct pci_slot *slot)
56945696
{
5695-
struct pci_dev *dev;
5697+
struct pci_dev *dev, *bridge = slot->bus->self;
56965698

56975699
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
56985700
if (!dev->slot || dev->slot != slot)
@@ -5702,12 +5704,18 @@ static void pci_slot_unlock(struct pci_slot *slot)
57025704
else
57035705
pci_dev_unlock(dev);
57045706
}
5707+
5708+
if (bridge)
5709+
pci_dev_unlock(bridge);
57055710
}
57065711

57075712
/* Return 1 on successful lock, 0 on contention */
57085713
static int pci_slot_trylock(struct pci_slot *slot)
57095714
{
5710-
struct pci_dev *dev;
5715+
struct pci_dev *dev, *bridge = slot->bus->self;
5716+
5717+
if (bridge && !pci_dev_trylock(bridge))
5718+
return 0;
57115719

57125720
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
57135721
if (!dev->slot || dev->slot != slot)
@@ -5732,6 +5740,9 @@ static int pci_slot_trylock(struct pci_slot *slot)
57325740
else
57335741
pci_dev_unlock(dev);
57345742
}
5743+
5744+
if (bridge)
5745+
pci_dev_unlock(bridge);
57355746
return 0;
57365747
}
57375748

0 commit comments

Comments
 (0)