From: Taku Izumi <izumi.taku@jp.fujitsu.com>
To: Taku Izumi <izumi.taku@jp.fujitsu.com>
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 4/6] ACPI, PCI: add acpi_pci_roots protection
Date: Mon, 3 Sep 2012 17:06:02 +0900 [thread overview]
Message-ID: <20120903170602.375b00cc.izumi.taku@jp.fujitsu.com> (raw)
In-Reply-To: <20120903165831.29aed72c.izumi.taku@jp.fujitsu.com>
Use mutex and RCU to protect global acpi_pci_roots list against
PCI host bridge hotplug operations.
RCU is used to avoid possible deadlock in function acpi_pci_find_root()
and acpi_get_pci_rootbridge_handle(). A possible call graph:
acpi_pci_register_driver()
mutex_lock(&acpi_pci_root_lock)
driver->add(root)
......
acpi_pci_find_root()
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
---
drivers/acpi/pci_root.c | 50 +++++++++++++++++++++++++++++++-----------------
1 file changed, 33 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
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/mutex.h>
+#include <linux/rculist.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/pci.h>
@@ -86,7 +87,7 @@ int acpi_pci_register_driver(struct acpi
mutex_lock(&acpi_pci_root_lock);
list_add_tail(&driver->node, &acpi_pci_drivers);
if (driver->add)
- list_for_each_entry(root, &acpi_pci_roots, node) {
+ list_for_each_entry_rcu(root, &acpi_pci_roots, node) {
driver->add(root->device->handle);
n++;
}
@@ -103,7 +104,7 @@ void acpi_pci_unregister_driver(struct a
mutex_lock(&acpi_pci_root_lock);
list_del(&driver->node);
if (driver->remove)
- list_for_each_entry(root, &acpi_pci_roots, node)
+ list_for_each_entry_rcu(root, &acpi_pci_roots, node)
driver->remove(root->device->handle);
mutex_unlock(&acpi_pci_root_lock);
}
@@ -112,14 +113,19 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
{
struct acpi_pci_root *root;
+ struct acpi_handle *handle = NULL;
- list_for_each_entry(root, &acpi_pci_roots, node)
+ rcu_read_lock();
+ list_for_each_entry_rcu(root, &acpi_pci_roots, node)
if ((root->segment == (u16) seg) &&
- (root->secondary.start == (u16) bus))
- return root->device->handle;
- return NULL;
-}
+ (root->secondary.start == (u16) bus)) {
+ handle = root->device->handle;
+ break;
+ }
+ rcu_read_unlock();
+ return handle;
+}
EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
/**
@@ -266,10 +272,14 @@ struct acpi_pci_root *acpi_pci_find_root
{
struct acpi_pci_root *root;
- list_for_each_entry(root, &acpi_pci_roots, node) {
- if (root->device->handle == handle)
+ rcu_read_lock();
+ list_for_each_entry_rcu(root, &acpi_pci_roots, node)
+ if (root->device->handle == handle) {
+ rcu_read_unlock();
return root;
- }
+ }
+ rcu_read_unlock();
+
return NULL;
}
EXPORT_SYMBOL_GPL(acpi_pci_find_root);
@@ -506,8 +516,9 @@ static int __devinit acpi_pci_root_add(s
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
- /* TBD: Locking */
- list_add_tail(&root->node, &acpi_pci_roots);
+ mutex_lock(&acpi_pci_root_lock);
+ list_add_tail_rcu(&root->node, &acpi_pci_roots);
+ mutex_unlock(&acpi_pci_root_lock);
printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
acpi_device_name(device), acpi_device_bid(device),
@@ -526,7 +537,7 @@ static int __devinit acpi_pci_root_add(s
"Bus %04x:%02x not present in PCI namespace\n",
root->segment, (unsigned int)root->secondary.start);
result = -ENODEV;
- goto end;
+ goto out_del_root;
}
/*
@@ -536,7 +547,7 @@ static int __devinit acpi_pci_root_add(s
*/
result = acpi_pci_bind_root(device);
if (result)
- goto end;
+ goto out_del_root;
/*
* PCI Routing Table
@@ -614,9 +625,12 @@ static int __devinit acpi_pci_root_add(s
return 0;
+out_del_root:
+ mutex_lock(&acpi_pci_root_lock);
+ list_del_rcu(&root->node);
+ mutex_unlock(&acpi_pci_root_lock);
+ synchronize_rcu();
end:
- if (!list_empty(&root->node))
- list_del(&root->node);
kfree(root);
return result;
}
@@ -646,11 +660,13 @@ static int acpi_pci_root_remove(struct a
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);
+ list_del_rcu(&root->node);
+ mutex_unlock(&acpi_pci_root_lock);
+ synchronize_rcu();
kfree(root);
return 0;
}
next prev parent reply other threads:[~2012-09-03 8:06 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-03 7:58 [PATCH v2 0/6] acpi,pci: hostbridge hotplug support Taku Izumi
2012-09-03 8:03 ` [PATCH v2 1/6] ACPI, PCI: Use normal list for struct acpi_pci_driver Taku Izumi
2012-09-03 8:04 ` [PATCH v2 2/6] ACPI, PCI: Notify acpi_pci_drivers when hot-plugging PCI root bridges Taku Izumi
2012-09-04 7:58 ` Kaneshige, Kenji
2012-09-04 19:12 ` Yinghai Lu
2012-09-05 4:32 ` Kaneshige, Kenji
2012-09-05 5:01 ` Yinghai Lu
2012-09-05 8:55 ` Kaneshige, Kenji
2012-09-03 8:05 ` [PATCH v2 3/6] ACPI, PCI: add acpi_pci_drivers protection Taku Izumi
2012-09-03 8:06 ` Taku Izumi [this message]
2012-09-12 23:40 ` [PATCH v2 4/6] ACPI, PCI: add acpi_pci_roots protection Bjorn Helgaas
2012-09-13 19:09 ` Yinghai Lu
2012-09-13 19:39 ` Bjorn Helgaas
2012-09-13 21:17 ` Yinghai Lu
2012-09-13 22:44 ` Yinghai Lu
2012-09-14 4:35 ` Taku Izumi
2012-09-14 14:43 ` Bjorn Helgaas
2012-09-15 3:23 ` Jiang Liu
2012-09-03 8:06 ` [PATCH v2 5/6] ACPI, PCI: add hostbridge removal function Taku Izumi
2012-09-03 8:07 ` [PATCH v2 6/6] ACPI, PCI: add resoruce-assign code for devices under hot-added hostbridge Taku Izumi
2012-09-03 20:27 ` Yinghai Lu
2012-09-07 9:26 ` Taku Izumi
2012-09-07 9:31 ` Taku Izumi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120903170602.375b00cc.izumi.taku@jp.fujitsu.com \
--to=izumi.taku@jp.fujitsu.com \
--cc=bhelgaas@google.com \
--cc=jiang.liu@huawei.com \
--cc=kaneshige.kenji@jp.fujitsu.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=yinghai@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).