summaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-13 23:27:26 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-23 04:00:28 +0200
commitff181e5a4f6b536e5f3f1601cd5c54e792cd9abc (patch)
treea2f3addfd9b74e8678dfe6001db2e884cac0b29b /drivers/pci/hotplug
parenta1d0abcea845730c4ff2f47897e28c2f11c79d4f (diff)
downloadlinux-ff181e5a4f6b536e5f3f1601cd5c54e792cd9abc.tar.gz
linux-ff181e5a4f6b536e5f3f1601cd5c54e792cd9abc.tar.bz2
linux-ff181e5a4f6b536e5f3f1601cd5c54e792cd9abc.zip
ACPI / hotplug / PCI: Clean up bridge_mutex usage
Do not acquire bridge_mutex around the addition of a slot to its bridge's list of slots and arount the addition of a function to its slot's list of functions, because that doesn't help anything right now (those lists are walked without any locking anyway). However, acquire bridge_mutex around the list walk in acpiphp_remove_slots() and use list_for_each_entry() there, because we terminate the walk as soon as we find the first matching entry. This prevents that list walk from colliding with bridge addition and removal. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 18c9e54990ee..e4b7f2bc94df 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -323,9 +323,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
INIT_LIST_HEAD(&slot->funcs);
mutex_init(&slot->crit_sect);
- mutex_lock(&bridge_mutex);
list_add_tail(&slot->node, &bridge->slots);
- mutex_unlock(&bridge_mutex);
/* Register slots for ejectable funtions only. */
if (acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) {
@@ -355,9 +353,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
slot_found:
newfunc->slot = slot;
- mutex_lock(&bridge_mutex);
list_add_tail(&newfunc->sibling, &slot->funcs);
- mutex_unlock(&bridge_mutex);
if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function),
&val, 60*1000))
@@ -1025,17 +1021,21 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
/* Destroy hotplug slots associated with the PCI bus */
void acpiphp_remove_slots(struct pci_bus *bus)
{
- struct acpiphp_bridge *bridge, *tmp;
+ struct acpiphp_bridge *bridge;
if (acpiphp_disabled)
return;
- list_for_each_entry_safe(bridge, tmp, &bridge_list, list)
+ mutex_lock(&bridge_mutex);
+ list_for_each_entry(bridge, &bridge_list, list)
if (bridge->pci_bus == bus) {
+ mutex_unlock(&bridge_mutex);
cleanup_bridge(bridge);
put_bridge(bridge);
- break;
+ return;
}
+
+ mutex_unlock(&bridge_mutex);
}
/**