PCI: Simplify disconnected marking
authorLukas Wunner <lukas@wunner.de>
Sun, 19 Aug 2018 14:29:00 +0000 (16:29 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 17 Sep 2018 21:34:35 +0000 (16:34 -0500)
Commit 89ee9f768003 ("PCI: Add device disconnected state") iterates over
the devices on a parent bus, marks each as disconnected, then marks
each device's children as disconnected using pci_walk_bus().

The same can be achieved more succinctly by calling pci_walk_bus() on
the parent bus.  Moreover, this does not need to wait until acquiring
pci_lock_rescan_remove(), so move it out of that critical section.

The critical section in err.c contains a pci_dev_get() / pci_dev_put()
pair which was apparently copy-pasted from pciehp_pci.c.  In the latter
it serves the purpose of holding the struct pci_dev in place until the
Command register is updated.  err.c doesn't do anything like that, hence
the pair is unnecessary.  Remove it.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Oza Pawandeep <poza@codeaurora.org>
Cc: Sinan Kaya <okaya@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
drivers/pci/hotplug/pciehp_pci.c
drivers/pci/pcie/err.c

index 5c58c22e0c084145115662855c6efadc0dea6268..3ef5c074424939e3628d2d3448fdf4b2de992aab 100644 (file)
@@ -74,6 +74,9 @@ void pciehp_unconfigure_device(struct slot *p_slot)
                 __func__, pci_domain_nr(parent), parent->number);
        pciehp_get_adapter_status(p_slot, &presence);
 
+       if (!presence)
+               pci_walk_bus(parent, pci_dev_set_disconnected, NULL);
+
        pci_lock_rescan_remove();
 
        /*
@@ -85,12 +88,6 @@ void pciehp_unconfigure_device(struct slot *p_slot)
        list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
                                         bus_list) {
                pci_dev_get(dev);
-               if (!presence) {
-                       pci_dev_set_disconnected(dev, NULL);
-                       if (pci_has_subordinate(dev))
-                               pci_walk_bus(dev->subordinate,
-                                            pci_dev_set_disconnected, NULL);
-               }
                pci_stop_and_remove_bus_device(dev);
                /*
                 * Ensure that no new Requests will be generated from
index 708fd3a0d6466063e825383983206ced863adf4a..cac406b6e9360b8d2d6899975a08e94dbdf488f8 100644 (file)
@@ -292,17 +292,13 @@ void pcie_do_fatal_recovery(struct pci_dev *dev, u32 service)
                udev = dev->bus->self;
 
        parent = udev->subordinate;
+       pci_walk_bus(parent, pci_dev_set_disconnected, NULL);
+
        pci_lock_rescan_remove();
        pci_dev_get(dev);
        list_for_each_entry_safe_reverse(pdev, temp, &parent->devices,
                                         bus_list) {
-               pci_dev_get(pdev);
-               pci_dev_set_disconnected(pdev, NULL);
-               if (pci_has_subordinate(pdev))
-                       pci_walk_bus(pdev->subordinate,
-                                    pci_dev_set_disconnected, NULL);
                pci_stop_and_remove_bus_device(pdev);
-               pci_dev_put(pdev);
        }
 
        result = reset_link(udev, service);