On Thu, May 30, 2024 at 06:04:35PM -0700, Dan Williams wrote: > @@ -5444,6 +5444,7 @@ static void pci_bus_lock(struct pci_bus *bus) > { > struct pci_dev *dev; > > + pci_dev_lock(bus->self); > list_for_each_entry(dev, &bus->devices, bus_list) { > pci_dev_lock(dev); > if (dev->subordinate) The very next line is: pci_bus_lock(dev->subordinate); The code had just locked "dev". The recursive call will then lock dev->subordinate->self, which is "dev", the same that was just locked a moment ago: deadlocked. Here's an idea: --- diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 46beaf1815fab..4f7cf693857f4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5487,8 +5487,9 @@ static void pci_bus_lock(struct pci_bus *bus) pci_dev_lock(bus->self); list_for_each_entry(dev, &bus->devices, bus_list) { - pci_dev_lock(dev); - if (dev->subordinate) + if (!dev->subordinate) + pci_dev_lock(dev); + else pci_bus_lock(dev->subordinate); } } @@ -5501,7 +5502,8 @@ static void pci_bus_unlock(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->subordinate) pci_bus_unlock(dev->subordinate); - pci_dev_unlock(dev); + else + pci_dev_unlock(dev); } pci_dev_unlock(bus->self); } --