Commit b8b66110 authored by Yinghai Lu's avatar Yinghai Lu Committed by Rafael J. Wysocki

PCI / ACPI: hold acpi_scan_lock during root bus hotplug

During merging the PCI tree with the PM/ACPI tree, Linus noticed
that we don't use the same lock using patten about ACPI PCI root as
acpiphp.

Here apply the same locking patten, and we need to execute
acpi_bus_hot_remove_device() via acpi_os_hotplug_execute()
as it also holds acpi_scan_lock.

[rjw: Changelog]
Reported-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
No-objection-from: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent aaf9d93b
...@@ -646,6 +646,7 @@ static void handle_root_bridge_insertion(acpi_handle handle) ...@@ -646,6 +646,7 @@ static void handle_root_bridge_insertion(acpi_handle handle)
static void handle_root_bridge_removal(struct acpi_device *device) static void handle_root_bridge_removal(struct acpi_device *device)
{ {
acpi_status status;
struct acpi_eject_event *ej_event; struct acpi_eject_event *ej_event;
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
...@@ -661,7 +662,9 @@ static void handle_root_bridge_removal(struct acpi_device *device) ...@@ -661,7 +662,9 @@ static void handle_root_bridge_removal(struct acpi_device *device)
ej_event->device = device; ej_event->device = device;
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
acpi_bus_hot_remove_device(ej_event); status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
if (ACPI_FAILURE(status))
kfree(ej_event);
} }
static void _handle_hotplug_event_root(struct work_struct *work) static void _handle_hotplug_event_root(struct work_struct *work)
...@@ -676,8 +679,9 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -676,8 +679,9 @@ static void _handle_hotplug_event_root(struct work_struct *work)
handle = hp_work->handle; handle = hp_work->handle;
type = hp_work->type; type = hp_work->type;
root = acpi_pci_find_root(handle); acpi_scan_lock_acquire();
root = acpi_pci_find_root(handle);
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
switch (type) { switch (type) {
...@@ -711,6 +715,7 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -711,6 +715,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
break; break;
} }
acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
kfree(buffer.pointer); kfree(buffer.pointer);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment