From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Mon, 3 Sep 2012 17:05:15 +0900 From: Taku Izumi To: Taku Izumi Cc: linux-pci@vger.kernel.org, bhelgaas@google.com, linux-acpi@vger.kernel.org, kaneshige.kenji@jp.fujitsu.com, yinghai@kernel.org, jiang.liu@huawei.com Subject: [PATCH v2 3/6] ACPI, PCI: add acpi_pci_drivers protection Message-Id: <20120903170515.876941ff.izumi.taku@jp.fujitsu.com> In-Reply-To: <20120903165831.29aed72c.izumi.taku@jp.fujitsu.com> References: <20120903165831.29aed72c.izumi.taku@jp.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Sender: linux-acpi-owner@vger.kernel.org List-ID: Use mutex to protect global acpi_pci_drivers list against PCI host bridge hotplug operations. Signed-off-by: Jiang Liu Signed-off-by: Yinghai Lu Signed-off-by: Taku Izumi --- drivers/acpi/pci_root.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) Index: Bjorn-next-0903/drivers/acpi/pci_root.c =================================================================== --- Bjorn-next-0903.orig/drivers/acpi/pci_root.c +++ Bjorn-next-0903/drivers/acpi/pci_root.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -71,6 +71,8 @@ static struct acpi_driver acpi_pci_root_ }, }; +/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ +static DEFINE_MUTEX(acpi_pci_root_lock); static LIST_HEAD(acpi_pci_roots); static LIST_HEAD(acpi_pci_drivers); @@ -81,34 +83,30 @@ int acpi_pci_register_driver(struct acpi int n = 0; struct acpi_pci_root *root; + mutex_lock(&acpi_pci_root_lock); list_add_tail(&driver->node, &acpi_pci_drivers); - - if (!driver->add) - return 0; - - list_for_each_entry(root, &acpi_pci_roots, node) { - driver->add(root->device->handle); - n++; - } + if (driver->add) + list_for_each_entry(root, &acpi_pci_roots, node) { + driver->add(root->device->handle); + n++; + } + mutex_unlock(&acpi_pci_root_lock); return n; } - EXPORT_SYMBOL(acpi_pci_register_driver); void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) { struct acpi_pci_root *root; + mutex_lock(&acpi_pci_root_lock); list_del(&driver->node); - - if (!driver->remove) - return; - - list_for_each_entry(root, &acpi_pci_roots, node) - driver->remove(root->device->handle); + if (driver->remove) + list_for_each_entry(root, &acpi_pci_roots, node) + driver->remove(root->device->handle); + mutex_unlock(&acpi_pci_root_lock); } - EXPORT_SYMBOL(acpi_pci_unregister_driver); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) @@ -628,9 +626,11 @@ static int acpi_pci_root_start(struct ac struct acpi_pci_root *root = acpi_driver_data(device); struct acpi_pci_driver *driver; + mutex_lock(&acpi_pci_root_lock); list_for_each_entry(driver, &acpi_pci_drivers, node) if (driver->add) driver->add(device->handle); + mutex_unlock(&acpi_pci_root_lock); pci_bus_add_devices(root->bus); @@ -642,9 +642,11 @@ static int acpi_pci_root_remove(struct a struct acpi_pci_root *root = acpi_driver_data(device); struct acpi_pci_driver *driver; + mutex_lock(&acpi_pci_root_lock); list_for_each_entry(driver, &acpi_pci_drivers, node) if (driver->remove) driver->remove(root->device->handle); + mutex_unlock(&acpi_pci_root_lock); device_set_run_wake(root->bus->bridge, false); pci_acpi_remove_bus_pm_notifier(device);