All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiang Liu <liuj97@gmail.com>
To: Bjorn Helgaas <bhelgaas@google.com>,
	Don Dutile <ddutile@redhat.com>, Yinghai Lu <yinghai@kernel.org>,
	Greg KH <gregkh@linuxfoundation.org>,
	Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Jiang Liu <jiang.liu@huawei.com>,
	Taku Izumi <izumi.taku@jp.fujitsu.com>,
	"Rafael J . Wysocki" <rjw@sisk.pl>,
	Yijing Wang <wangyijing@huawei.com>,
	Xinwei Hu <huxinwei@huawei.com>,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	Jiang Liu <liuj97@gmail.com>
Subject: [RFC PATCH v1 08/22] PCI: introduce hotplug safe search interfaces for PCI bus/device
Date: Wed,  8 Aug 2012 00:10:48 +0800	[thread overview]
Message-ID: <1344355862-2726-9-git-send-email-jiang.liu@huawei.com> (raw)
In-Reply-To: <1344355862-2726-1-git-send-email-jiang.liu@huawei.com>

Function pci_find_bus() is not hotplug safe because it doesn't hold any
reference on the returned bus, so the bus may be destroyed by hotplug
operations just after returning from pci_find_bus.

This patch introduces a hotplug safe interface to get and lock a specific
PCI bus. It also provides several help interfaces to reduce code complexity.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
---
 drivers/pci/bus.c    |   34 ++++++++++++++++++++++++++++++++++
 drivers/pci/search.c |   44 ++++++++++++++++++++++++++++++++++----------
 include/linux/pci.h  |   10 ++++++++++
 3 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index aa25fcf..b6aacaa 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -426,6 +426,40 @@ void pci_bus_change_state(struct pci_bus *bus, int old, int new, bool unlock)
 }
 EXPORT_SYMBOL(pci_bus_change_state);
 
+struct pci_bus *__pci_get_and_lock_bus(int domain, int busnr, int states)
+{
+	struct pci_bus *bus;
+
+	bus = pci_get_bus(domain, busnr);
+	if (bus && pci_bus_lock_states(bus, states) < 0) {
+		pci_bus_put(bus);
+		bus = NULL;
+	}
+
+	return bus;
+}
+EXPORT_SYMBOL(__pci_get_and_lock_bus);
+
+struct pci_bus *pci_lock_subordinate(struct pci_dev *dev, int states)
+{
+	struct pci_bus *bus = dev->subordinate;
+
+	if (bus && pci_bus_lock_states(bus, states) > 0)
+		return bus;
+
+	return NULL;
+}
+EXPORT_SYMBOL(pci_lock_subordinate);
+
+void pci_unlock_and_put_bus(struct pci_bus *bus)
+{
+	if (bus) {
+		pci_bus_unlock(bus);
+		pci_bus_put(bus);
+	}
+}
+EXPORT_SYMBOL(pci_unlock_and_put_bus);
+
 EXPORT_SYMBOL(pci_bus_alloc_resource);
 EXPORT_SYMBOL_GPL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index f1147a7..c0a8a2b 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -69,6 +69,35 @@ static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
 }
 
 /**
+ * pci_get_bus - get PCI bus from a given domain and bus number
+ * @domain: number of PCI domain to search
+ * @busnr: number of desired PCI bus
+ *
+ * Given a PCI bus number and domain number, the desired PCI bus is located
+ * in the global list of PCI buses. If the bus is found, a reference count
+ * is held on the returned PCI bus. If no bus is found, %NULL is returned.
+ */
+struct pci_bus *pci_get_bus(int domain, int busnr)
+{
+	struct pci_bus *bus;
+	struct pci_bus *tmp_bus = NULL;
+
+	down_read(&pci_bus_sem);
+	list_for_each_entry(bus, &pci_root_buses, node)
+		if (pci_domain_nr(bus) == domain) {
+			tmp_bus = pci_do_find_bus(bus, busnr);
+			if (tmp_bus) {
+				pci_bus_get(tmp_bus);
+				break;
+			}
+		}
+	up_read(&pci_bus_sem);
+
+	return tmp_bus;
+}
+EXPORT_SYMBOL(pci_get_bus);
+
+/**
  * pci_find_bus - locate PCI bus from a given domain and bus number
  * @domain: number of PCI domain to search
  * @busnr: number of desired PCI bus
@@ -79,17 +108,12 @@ static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
  */
 struct pci_bus * pci_find_bus(int domain, int busnr)
 {
-	struct pci_bus *bus = NULL;
-	struct pci_bus *tmp_bus;
+	struct pci_bus *bus;
 
-	while ((bus = pci_find_next_bus(bus)) != NULL)  {
-		if (pci_domain_nr(bus) != domain)
-			continue;
-		tmp_bus = pci_do_find_bus(bus, busnr);
-		if (tmp_bus)
-			return tmp_bus;
-	}
-	return NULL;
+	bus = pci_get_bus(domain, busnr);
+	pci_bus_put(bus);
+
+	return bus;
 }
 
 /**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e2ef517..9e52e88 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -488,6 +488,15 @@ extern int pci_bus_lock_states(struct pci_bus *bus, int states);
 extern void pci_bus_unlock(struct pci_bus *bus);
 extern void pci_bus_change_state(struct pci_bus *bus, int new, int old,
 				 bool unlock);
+extern struct pci_bus *pci_lock_subordinate(struct pci_dev *dev, int states);
+extern struct pci_bus *__pci_get_and_lock_bus(int domain, int busnr,
+					      int states);
+extern void pci_unlock_and_put_bus(struct pci_bus *bus);
+
+static inline struct pci_bus *pci_get_and_lock_bus(int domain, int busnr)
+{
+	return __pci_get_and_lock_bus(domain, busnr, PCI_BUS_STATE_WORKING);
+}
 
 #define pci_bus_b(n)	list_entry(n, struct pci_bus, node)
 #define to_pci_bus(n)	container_of(n, struct pci_bus, dev)
@@ -734,6 +743,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 			     struct pci_bus_region *region);
 void pcibios_scan_specific_bus(int busn);
 extern struct pci_bus *pci_find_bus(int domain, int busnr);
+struct pci_bus *pci_get_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
 				      struct pci_ops *ops, void *sysdata);
-- 
1.7.9.5


  parent reply	other threads:[~2012-08-07 16:19 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-07 16:10 [RFC PATCH v1 00/22] introduce PCI bus lock to serialize PCI hotplug operations Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 01/22] PCI: use pci_get_domain_bus_and_slot() to avoid race conditions Jiang Liu
2012-09-11 22:00   ` Bjorn Helgaas
2012-09-12  8:37     ` Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 02/22] PCI: trivial cleanups for drivers/pci/remove.c Jiang Liu
2012-09-11 22:03   ` Bjorn Helgaas
2012-09-12  8:50     ` Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 03/22] PCI: change PCI device management code to better follow device model Jiang Liu
2012-09-11 22:03   ` Bjorn Helgaas
2012-08-07 16:10 ` [RFC PATCH v1 04/22] PCI: split PCI bus device registration into two stages Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 05/22] PCI: introduce pci_bus_{get|put}() to manage PCI bus reference count Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 06/22] PCI: use a global lock to serialize PCI root bridge hotplug operations Jiang Liu
2012-09-11 22:57   ` Bjorn Helgaas
2012-09-12 15:42     ` Jiang Liu
2012-09-12 16:51       ` Bjorn Helgaas
2012-09-13 16:00         ` [PATCH 1/2] PCI: introduce root bridge hotplug safe interfaces to walk root buses Jiang Liu
2012-09-13 17:40           ` Bjorn Helgaas
2012-09-17 15:55             ` Jiang Liu
2012-09-17 16:24               ` Bjorn Helgaas
2012-09-18 21:39                 ` Bjorn Helgaas
2012-09-21 16:07                   ` [PATCH v4] PCI: introduce two interfaces to walk PCI buses Jiang Liu
2012-09-26 20:14                     ` Bjorn Helgaas
2012-09-13 16:00         ` [PATCH 2/2] PCI: remove host bridge hotplug unsafe interface pci_get_next_bus() Jiang Liu
2012-09-17 15:51         ` [RFC PATCH v1 06/22] PCI: use a global lock to serialize PCI root bridge hotplug operations Jiang Liu
2012-09-20 18:49         ` Paul E. McKenney
2012-08-07 16:10 ` [RFC PATCH v1 07/22] PCI: introduce PCI bus lock to serialize PCI " Jiang Liu
2012-09-11 23:24   ` Bjorn Helgaas
2012-08-07 16:10 ` Jiang Liu [this message]
2012-08-07 16:10 ` [RFC PATCH v1 09/22] PCI: enhance PCI probe logic to support PCI bus lock mechanism Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 10/22] PCI: enhance PCI bus specific " Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 11/22] PCI: enhance PCI resource assignment " Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 12/22] PCI: enhance PCI remove " Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 13/22] PCI: make each PCI device hold a reference to its parent PCI bus Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 14/22] PCI/sysfs: use PCI bus lock to avoid race conditions Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 15/22] PCI/eeepc: " Jiang Liu
2012-09-11 23:18   ` Bjorn Helgaas
2012-09-12 14:24     ` [PATCH] eeepc-laptop: fix device reference count leakage in eeepc_rfkill_hotplug() Jiang Liu
2012-09-12 19:59       ` Bjorn Helgaas
2012-08-07 16:10 ` [RFC PATCH v1 16/22] PCI/asus-wmi: use PCI bus lock to avoid race conditions Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 17/22] PCI/pciehp: " Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 18/22] PCI/acpiphp: " Jiang Liu
2012-08-07 16:10 ` [RFC PATCH v1 19/22] PCI/x86: enable PCI bus lock mechanism for x86 platforms Jiang Liu
2012-09-11 23:22   ` Bjorn Helgaas
2012-09-12  9:56     ` Jiang Liu
2012-08-07 16:11 ` [RFC PATCH v1 20/22] PCI/IA64: enable PCI bus lock mechanism for IA64 platforms Jiang Liu
2012-08-07 16:11 ` [RFC PATCH v1 21/22] PCI: cleanups for PCI bus lock implementation Jiang Liu
2012-09-11 23:21   ` Bjorn Helgaas
2012-09-12  8:58     ` Jiang Liu
2012-08-07 16:11 ` [RFC PATCH v1 22/22] PCI: unexport pci_root_buses Jiang Liu
2012-08-07 18:11 ` [RFC PATCH v1 00/22] introduce PCI bus lock to serialize PCI hotplug operations Don Dutile
2012-08-08 15:49   ` Jiang Liu

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=1344355862-2726-9-git-send-email-jiang.liu@huawei.com \
    --to=liuj97@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=ddutile@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=huxinwei@huawei.com \
    --cc=izumi.taku@jp.fujitsu.com \
    --cc=jiang.liu@huawei.com \
    --cc=kaneshige.kenji@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=rjw@sisk.pl \
    --cc=wangyijing@huawei.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.