Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff181e5a authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent a1d0abce
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -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);
}

/**