PCI: Simplify pci_dev_reset_slot_function()
authorLukas Wunner <lukas@wunner.de>
Tue, 21 Jul 2020 11:24:51 +0000 (13:24 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 17 Sep 2020 21:25:45 +0000 (16:25 -0500)
pci_dev_reset_slot_function() refuses to reset a hotplug slot if it is
shared by multiple pci_devs.  That's the case if and only if the slot is
occupied by a multifunction device.

Simplify the function to check the device's multifunction flag instead
of iterating over the devices on the bus.  (Iterating over the devices
requires holding pci_bus_sem, which the function erroneously does not
acquire.)

Link: https://lore.kernel.org/r/c6aab5af096f7b1b3db57f6335cebba8f0fcca89.1595330431.git.lukas@wunner.de
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
drivers/pci/pci.c

index 84b9937..b630d53 100644 (file)
@@ -4917,16 +4917,10 @@ static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe)
 
 static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
 {
-       struct pci_dev *pdev;
-
-       if (dev->subordinate || !dev->slot ||
+       if (dev->multifunction || dev->subordinate || !dev->slot ||
            dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
                return -ENOTTY;
 
-       list_for_each_entry(pdev, &dev->bus->devices, bus_list)
-               if (pdev != dev && pdev->slot == dev->slot)
-                       return -ENOTTY;
-
        return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
 }