mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
PCI: Fix pci_slot_lock () device locking
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
This commit is contained in:
parent
9368d1ee62
commit
1f5e57c622
|
|
@ -5290,10 +5290,9 @@ static int pci_bus_trylock(struct pci_bus *bus)
|
|||
/* Do any devices on or below this slot prevent a bus reset? */
|
||||
static bool pci_slot_resettable(struct pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev *dev, *bridge = slot->bus->self;
|
||||
|
||||
if (slot->bus->self &&
|
||||
(slot->bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
|
||||
if (bridge && (bridge->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
|
||||
return false;
|
||||
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
|
||||
|
|
@ -5310,7 +5309,10 @@ static bool pci_slot_resettable(struct pci_slot *slot)
|
|||
/* Lock devices from the top of the tree down */
|
||||
static void pci_slot_lock(struct pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev *dev, *bridge = slot->bus->self;
|
||||
|
||||
if (bridge)
|
||||
pci_dev_lock(bridge);
|
||||
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
|
||||
if (!dev->slot || dev->slot != slot)
|
||||
|
|
@ -5325,7 +5327,7 @@ static void pci_slot_lock(struct pci_slot *slot)
|
|||
/* Unlock devices from the bottom of the tree up */
|
||||
static void pci_slot_unlock(struct pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev *dev, *bridge = slot->bus->self;
|
||||
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
|
||||
if (!dev->slot || dev->slot != slot)
|
||||
|
|
@ -5335,12 +5337,18 @@ static void pci_slot_unlock(struct pci_slot *slot)
|
|||
else
|
||||
pci_dev_unlock(dev);
|
||||
}
|
||||
|
||||
if (bridge)
|
||||
pci_dev_unlock(bridge);
|
||||
}
|
||||
|
||||
/* Return 1 on successful lock, 0 on contention */
|
||||
static int pci_slot_trylock(struct pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct pci_dev *dev, *bridge = slot->bus->self;
|
||||
|
||||
if (bridge && !pci_dev_trylock(bridge))
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
|
||||
if (!dev->slot || dev->slot != slot)
|
||||
|
|
@ -5363,6 +5371,9 @@ static int pci_slot_trylock(struct pci_slot *slot)
|
|||
else
|
||||
pci_dev_unlock(dev);
|
||||
}
|
||||
|
||||
if (bridge)
|
||||
pci_dev_unlock(bridge);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user