aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-10 09:23:14 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-01-14 14:14:25 -0500
commit7a3bb55ebd1cb04f08dd68cf60af24b434f8cc2a (patch)
treebe458b65d628b313efc2d32abc5646ee91e517e7 /drivers/acpi/pci_root.c
parent9d16947b75831acd317ab9a53e0e94d160731d33 (diff)
ACPI / PCI: Use global PCI rescan-remove locking in PCI root hotplug
Multiple race conditions are possible between the addition and removal of PCI devices during ACPI PCI host bridge hotplug and the generic PCI bus rescan and device removal that can be triggered via sysfs. To avoid those race conditions make the ACPI PCI host bridge addition and removal code use global PCI rescan-remove locking. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0703bff5e60e..07ee02aa3c51 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -596,7 +596,9 @@ static int acpi_pci_root_add(struct acpi_device *device,
596 pci_assign_unassigned_root_bus_resources(root->bus); 596 pci_assign_unassigned_root_bus_resources(root->bus);
597 } 597 }
598 598
599 pci_lock_rescan_remove();
599 pci_bus_add_devices(root->bus); 600 pci_bus_add_devices(root->bus);
601 pci_unlock_rescan_remove();
600 return 1; 602 return 1;
601 603
602end: 604end:
@@ -608,6 +610,8 @@ static void acpi_pci_root_remove(struct acpi_device *device)
608{ 610{
609 struct acpi_pci_root *root = acpi_driver_data(device); 611 struct acpi_pci_root *root = acpi_driver_data(device);
610 612
613 pci_lock_rescan_remove();
614
611 pci_stop_root_bus(root->bus); 615 pci_stop_root_bus(root->bus);
612 616
613 device_set_run_wake(root->bus->bridge, false); 617 device_set_run_wake(root->bus->bridge, false);
@@ -615,6 +619,8 @@ static void acpi_pci_root_remove(struct acpi_device *device)
615 619
616 pci_remove_root_bus(root->bus); 620 pci_remove_root_bus(root->bus);
617 621
622 pci_unlock_rescan_remove();
623
618 kfree(root); 624 kfree(root);
619} 625}
620 626