From c4ec84c7db0e4b01ed40cc2388f16ae5c6513cc0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 14 Jan 2014 12:03:14 -0700 Subject: PCI: hotplug: Use global PCI rescan-remove locking Multiple race conditions are possible between PCI hotplug and the generic PCI bus rescan and device removal that can be triggered via sysfs. To avoid those race conditions make PCI hotplug use global PCI rescan-remove locking. Signed-off-by: Rafael J. Wysocki Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_core.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/pci/hotplug/ibmphp_core.c') diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index efdc13a..cf3ac1e 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -718,6 +718,8 @@ static void ibm_unconfigure_device(struct pci_func *func) func->device, func->function); debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); + pci_lock_rescan_remove(); + for (j = 0; j < 0x08; j++) { temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); if (temp) { @@ -725,7 +727,10 @@ static void ibm_unconfigure_device(struct pci_func *func) pci_dev_put(temp); } } + pci_dev_put(func->dev); + + pci_unlock_rescan_remove(); } /* @@ -780,6 +785,8 @@ static int ibm_configure_device(struct pci_func *func) int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */ + pci_lock_rescan_remove(); + if (!(bus_structure_fixup(func->busno))) flag = 1; if (func->dev == NULL) @@ -789,7 +796,7 @@ static int ibm_configure_device(struct pci_func *func) if (func->dev == NULL) { struct pci_bus *bus = pci_find_bus(0, func->busno); if (!bus) - return 0; + goto out; num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function)); @@ -800,7 +807,7 @@ static int ibm_configure_device(struct pci_func *func) PCI_DEVFN(func->device, func->function)); if (func->dev == NULL) { err("ERROR... : pci_dev still NULL\n"); - return 0; + goto out; } } if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { @@ -810,6 +817,8 @@ static int ibm_configure_device(struct pci_func *func) pci_bus_add_devices(child); } + out: + pci_unlock_rescan_remove(); return 0; } -- cgit v1.1