2013-05-14 16:52:17

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 01/18] PCI: introduce hotplug-safe PCI bus iterators

Introduce hotplug-safe PCI bus iterators as below, which hold a
reference on the returned PCI bus object.
bool pci_bus_exists(int domain, int busnr);
struct pci_bus *pci_get_bus(int domain, int busnr);
struct pci_bus *pci_get_next_bus(struct pci_bus *from);
struct pci_bus *pci_get_next_root_bus(struct pci_bus *from);
#define for_each_pci_bus(b) for (b = NULL; (b = pci_get_next_bus(b)); )
#define for_each_pci_root_bus(b) \
for (b = NULL; (b = pci_get_next_root_bus(b)); )

The long-term goal is to remove hotplug-unsafe pci_find_bus(),
pci_find_next_bus() and the global pci_root_buses list.

These new interfaces may be a littler slower than existing interfaces,
but it should be acceptable because they are not used on hot paths.

Signed-off-by: Jiang Liu <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/pci/pci.h | 1 +
drivers/pci/probe.c | 2 +-
drivers/pci/search.c | 159 +++++++++++++++++++++++++++++++++++++++++----------
include/linux/pci.h | 23 +++++++-
4 files changed, 153 insertions(+), 32 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 68678ed..8fe15f6 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -126,6 +126,7 @@ static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }

/* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem;
+extern struct class pcibus_class;

extern raw_spinlock_t pci_lock;

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e59433a..6b77333 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -93,7 +93,7 @@ static void release_pcibus_dev(struct device *dev)
kfree(pci_bus);
}

-static struct class pcibus_class = {
+struct class pcibus_class = {
.name = "pci_bus",
.dev_release = &release_pcibus_dev,
.dev_attrs = pcibus_dev_attrs,
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index d0627fa..16ccaf8 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -52,20 +52,27 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
return tmp;
}

-static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
+struct pci_bus_match_arg {
+ int domain;
+ int bus;
+};
+
+static int pci_match_bus(struct device *dev, const void *data)
{
- struct pci_bus* child;
- struct list_head *tmp;
+ struct pci_bus *bus = to_pci_bus(dev);
+ const struct pci_bus_match_arg *arg = data;

- if(bus->number == busnr)
- return bus;
+ return (pci_domain_nr(bus) == arg->domain && bus->number == arg->bus);
+}

- list_for_each(tmp, &bus->children) {
- child = pci_do_find_bus(pci_bus_b(tmp), busnr);
- if(child)
- return child;
- }
- return NULL;
+static int pci_match_next_bus(struct device *dev, const void *data)
+{
+ return 1;
+}
+
+static int pci_match_next_root_bus(struct device *dev, const void *data)
+{
+ return pci_is_root_bus(to_pci_bus(dev));
}

/**
@@ -76,20 +83,19 @@ static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
* 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 pointer to its
* data structure is returned. If no bus is found, %NULL is returned.
+ *
+ * Note: it's not hotplug safe, the returned bus may be destroyed at any time.
+ * Please use pci_get_bus() instead which holds a reference on the returned
+ * PCI bus.
*/
-struct pci_bus * pci_find_bus(int domain, int 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;
}

/**
@@ -100,21 +106,114 @@ struct pci_bus * pci_find_bus(int domain, int busnr)
* initiated by passing %NULL as the @from argument. Otherwise if
* @from is not %NULL, searches continue from next device on the
* global list.
+ *
+ * Note: it's not hotplug safe, the returned bus may be destroyed at any time.
+ * Please use pci_get_next_root_bus() instead which holds a reference
+ * on the returned PCI root bus.
*/
struct pci_bus *
pci_find_next_bus(const struct pci_bus *from)
{
- struct list_head *n;
- struct pci_bus *b = NULL;
+ struct device *dev = from ? (struct device *)&from->dev : NULL;
+
+ dev = class_find_device(&pcibus_class, dev, NULL,
+ &pci_match_next_root_bus);
+ if (dev) {
+ put_device(dev);
+ return to_pci_bus(dev);
+ }
+
+ return NULL;
+}
+
+bool pci_bus_exists(int domain, int busnr)
+{
+ struct device *dev;
+ struct pci_bus_match_arg arg = { domain, busnr };

WARN_ON(in_interrupt());
- down_read(&pci_bus_sem);
- n = from ? from->node.next : pci_root_buses.next;
- if (n != &pci_root_buses)
- b = pci_bus_b(n);
- up_read(&pci_bus_sem);
- return b;
+ dev = class_find_device(&pcibus_class, NULL, &arg, &pci_match_bus);
+ if (dev)
+ put_device(dev);
+
+ return dev != NULL;
+}
+EXPORT_SYMBOL(pci_bus_exists);
+
+/**
+ * pci_get_bus - locate 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.
+ * If the bus is found, a pointer to its data structure is returned.
+ * If no bus is found, %NULL is returned.
+ * Caller needs to release the returned bus by calling pci_bus_put().
+ */
+struct pci_bus *pci_get_bus(int domain, int busnr)
+{
+ struct device *dev;
+ struct pci_bus_match_arg arg = { domain, busnr };
+
+ WARN_ON(in_interrupt());
+ dev = class_find_device(&pcibus_class, NULL, &arg, &pci_match_bus);
+ if (dev)
+ return to_pci_bus(dev);
+
+ return NULL;
+}
+EXPORT_SYMBOL(pci_get_bus);
+
+/**
+ * pci_get_next_bus - begin or continue searching for a PCI bus
+ * @from: Previous PCI bus found, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI busses. If a PCI bus is found,
+ * the reference count to the bus is incremented and a pointer to it is
+ * returned. Otherwise, %NULL is returned. A new search is initiated by
+ * passing %NULL as the @from argument. Otherwise if @from is not %NULL,
+ * searches continue from next bus on the global list. The reference count
+ * for @from is always decremented if it is not %NULL.
+ */
+struct pci_bus *pci_get_next_bus(struct pci_bus *from)
+{
+ struct device *dev = from ? &from->dev : NULL;
+
+ WARN_ON(in_interrupt());
+ dev = class_find_device(&pcibus_class, dev, NULL, &pci_match_next_bus);
+ pci_bus_put(from);
+ if (dev)
+ return to_pci_bus(dev);
+
+ return NULL;
+}
+EXPORT_SYMBOL(pci_get_next_bus);
+
+/**
+ * pci_find_next_root_bus - begin or continue searching for a PCI root bus
+ * @from: Previous PCI bus found, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI root busses. If a PCI bus is found,
+ * the reference count to the root bus is incremented and a pointer to it is
+ * returned. Otherwise, %NULL is returned. A new search is initiated by
+ * passing %NULL as the @from argument. Otherwise if @from is not %NULL,
+ * searches continue from next root bus on the global list. The reference
+ * count for @from is always decremented if it is not %NULL.
+ */
+struct pci_bus *pci_get_next_root_bus(struct pci_bus *from)
+{
+ struct device *dev = from ? &from->dev : NULL;
+
+ WARN_ON(in_interrupt());
+ dev = class_find_device(&pcibus_class, dev, NULL,
+ &pci_match_next_root_bus);
+ pci_bus_put(from);
+ if (dev)
+ return to_pci_bus(dev);
+
+ return NULL;
}
+EXPORT_SYMBOL(pci_get_next_root_bus);

/**
* pci_get_slot - locate PCI device for a given PCI slot
diff --git a/include/linux/pci.h b/include/linux/pci.h
index cc4ce27..c88d4e6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -454,6 +454,9 @@ struct pci_bus {

#define pci_bus_b(n) list_entry(n, struct pci_bus, node)
#define to_pci_bus(n) container_of(n, struct pci_bus, dev)
+#define for_each_pci_bus(b) for (b = NULL; (b = pci_get_next_bus(b)); )
+#define for_each_pci_root_bus(b) \
+ for (b = NULL; (b = pci_get_next_root_bus(b)); )

/*
* Returns true if the pci bus is root (behind host-pci bridge),
@@ -718,7 +721,6 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
void pcibios_scan_specific_bus(int busn);
-struct pci_bus *pci_find_bus(int domain, int busnr);
void pci_bus_add_devices(const struct pci_bus *bus);
struct pci_bus * __deprecated pci_scan_bus_parented(struct device *parent,
int bus, struct pci_ops *ops, void *sysdata);
@@ -778,8 +780,15 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap);
int pci_find_next_ext_capability(struct pci_dev *dev, int pos, int cap);
int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
+
+struct pci_bus *pci_find_bus(int domain, int busnr);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);

+bool pci_bus_exists(int domain, int busnr);
+struct pci_bus *pci_get_bus(int domain, int busnr);
+struct pci_bus *pci_get_next_bus(struct pci_bus *from);
+struct pci_bus *pci_get_next_root_bus(struct pci_bus *from);
+
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
struct pci_dev *from);
struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
@@ -1429,6 +1438,18 @@ static inline void pci_unblock_cfg_access(struct pci_dev *dev)
static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
{ return NULL; }

+static inline bool pci_bus_exists(int domain, int busnr)
+{ return false; }
+
+static inline struct pci_bus *pci_get_bus(int domain, int busnr)
+{ return NULL; }
+
+static inline struct pci_bus *pci_get_next_bus(struct pci_bus *from)
+{ return NULL; }
+
+static inline struct pci_bus *pci_get_next_root_bus(struct pci_bus *from)
+{ return NULL; }
+
static inline struct pci_dev *pci_get_slot(struct pci_bus *bus,
unsigned int devfn)
{ return NULL; }
--
1.8.1.2


2013-05-14 16:52:29

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 03/18] PCI, hotplug: use hotplug-safe iterators to walk PCI buses

Enhance PCI hotplug drivers to use hotplug-safe iterators to walk
PCI buses.

In other words, replace pci_find_bus(), pci_find_next_bus() and
pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
and pci_get_next_root_bus() etc.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Jiri Kosina <[email protected]>
Cc: Masanari Iida <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Toshi Kani <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/pci/hotplug-pci.c | 2 +-
drivers/pci/hotplug/ibmphp_core.c | 8 +++++---
drivers/pci/hotplug/ibmphp_ebda.c | 8 ++++++--
drivers/pci/hotplug/sgi_hotplug.c | 3 ++-
drivers/pci/hotplug/shpchp_sysfs.c | 2 +-
5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c
index 6258dc2..18533ed 100644
--- a/drivers/pci/hotplug-pci.c
+++ b/drivers/pci/hotplug-pci.c
@@ -11,7 +11,7 @@ int __ref pci_hp_add_bridge(struct pci_dev *dev)
int end = parent->busn_res.end;

for (busnr = start; busnr <= end; busnr++) {
- if (!pci_find_bus(pci_domain_nr(parent), busnr))
+ if (!pci_bus_exists(pci_domain_nr(parent), busnr))
break;
}
if (busnr-- > end) {
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index cbd72d8..fb47695 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -739,7 +739,7 @@ static u8 bus_structure_fixup(u8 busno)
struct pci_dev *dev;
u16 l;

- if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
+ if (pci_bus_exists(0, busno) || !(ibmphp_find_same_bus_num(busno)))
return 1;

bus = kmalloc(sizeof(*bus), GFP_KERNEL);
@@ -787,7 +787,7 @@ static int ibm_configure_device(struct pci_func *func)
PCI_DEVFN(func->device, func->function));

if (func->dev == NULL) {
- struct pci_bus *bus = pci_find_bus(0, func->busno);
+ struct pci_bus *bus = pci_get_bus(0, func->busno);
if (!bus)
return 0;

@@ -795,6 +795,7 @@ static int ibm_configure_device(struct pci_func *func)
PCI_DEVFN(func->device, func->function));
if (num)
pci_bus_add_devices(bus);
+ pci_bus_put(bus);

func->dev = pci_get_bus_and_slot(func->busno,
PCI_DEVFN(func->device, func->function));
@@ -1315,13 +1316,14 @@ static int __init ibmphp_init(void)
goto exit;
}

- bus = pci_find_bus(0, 0);
+ bus = pci_get_bus(0, 0);
if (!bus) {
err("Can't find the root pci bus, can not continue\n");
rc = -ENODEV;
goto error;
}
memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
+ pci_bus_put(bus);

ibmphp_debug = debug;

diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 9df78bc..e17f271 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -978,9 +978,13 @@ static int __init ebda_rsrc_controller (void)
} /* each hpc */

list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
+ struct pci_bus *bus = pci_get_bus(0, tmp_slot->bus);
+
+ BUG_ON(!bus);
snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot));
- pci_hp_register(tmp_slot->hotplug_slot,
- pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name);
+ pci_hp_register(tmp_slot->hotplug_slot, bus, tmp_slot->device,
+ name);
+ pci_bus_put(bus);
}

print_ebda_hpc ();
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index b2781df..5c69bda 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -684,7 +684,7 @@ static int __init sn_pci_hotplug_init(void)

INIT_LIST_HEAD(&sn_hp_list);

- while ((pci_bus = pci_find_next_bus(pci_bus))) {
+ for_each_pci_root_bus(pci_bus) {
if (!pci_bus->sysdata)
continue;

@@ -703,6 +703,7 @@ static int __init sn_pci_hotplug_init(void)
break;
}
}
+ pci_bus_put(pci_bus);

return registered == 1 ? 0 : -ENODEV;
}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index e8c31fe..e7a5dd2 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -74,7 +74,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha
}
out += sprintf(out, "Free resources: bus numbers\n");
for (busnr = bus->busn_res.start; busnr <= bus->busn_res.end; busnr++) {
- if (!pci_find_bus(pci_domain_nr(bus), busnr))
+ if (!pci_bus_exists(pci_domain_nr(bus), busnr))
break;
}
if (busnr < bus->busn_res.end)
--
1.8.1.2

2013-05-14 16:52:24

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 02/18] PCI, core: use hotplug-safe iterators to walk PCI buses

Enhance PCI core to use hotplug-safe iterators to walk PCI buses.

In other words, replace pci_find_bus(), pci_find_next_bus() and
pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
and pci_get_next_root_bus() etc.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Jeremy Fitzhardinge <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/pci/pci-sysfs.c | 2 +-
drivers/pci/pcie/pme.c | 5 +++--
drivers/pci/probe.c | 15 +++++++++------
drivers/pci/setup-bus.c | 14 ++++++--------
drivers/pci/xen-pcifront.c | 3 ++-
5 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 5b4a9d9..fcc4bb2 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -296,7 +296,7 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,

if (val) {
mutex_lock(&pci_remove_rescan_mutex);
- while ((b = pci_find_next_bus(b)) != NULL)
+ for_each_pci_root_bus(b)
pci_rescan_bus(b);
mutex_unlock(&pci_remove_rescan_mutex);
}
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 795db1f..1ed38a3 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -132,7 +132,7 @@ static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn)
static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
{
u8 busnr = req_id >> 8, devfn = req_id & 0xff;
- struct pci_bus *bus;
+ struct pci_bus *bus = NULL;
struct pci_dev *dev;
bool found = false;

@@ -161,7 +161,7 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
}

/* Second, find the bus the source device is on. */
- bus = pci_find_bus(pci_domain_nr(port->bus), busnr);
+ bus = pci_get_bus(pci_domain_nr(port->bus), busnr);
if (!bus)
goto out;

@@ -206,6 +206,7 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
}

out:
+ pci_bus_put(bus);
if (!found)
dev_dbg(&port->dev, "Spurious native PME interrupt!\n");
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6b77333..cc5e432 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -733,7 +733,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
*/
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
{
- struct pci_bus *child;
+ struct pci_bus *child = NULL;
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
u32 buses, i, j = 0;
u16 bctl;
@@ -785,7 +785,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
* However, we continue to descend down the hierarchy and
* scan remaining child buses.
*/
- child = pci_find_bus(pci_domain_nr(bus), secondary);
+ child = pci_get_bus(pci_domain_nr(bus), secondary);
if (!child) {
child = pci_add_new_bus(bus, dev, secondary);
if (!child)
@@ -793,6 +793,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
child->primary = primary;
pci_bus_insert_busn_res(child, secondary, subordinate);
child->bridge_ctl = bctl;
+ pci_bus_get(child);
}

cmax = pci_scan_child_bus(child);
@@ -824,12 +825,13 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
/* Prevent assigning a bus number that already exists.
* This can happen when a bridge is hot-plugged, so in
* this case we only re-scan this bus. */
- child = pci_find_bus(pci_domain_nr(bus), max+1);
+ child = pci_get_bus(pci_domain_nr(bus), max+1);
if (!child) {
child = pci_add_new_bus(bus, dev, ++max);
if (!child)
goto out;
pci_bus_insert_busn_res(child, max, 0xff);
+ pci_bus_get(child);
}
buses = (buses & 0xff000000)
| ((unsigned int)(child->primary) << 0)
@@ -874,8 +876,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
*/
for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) {
struct pci_bus *parent = bus;
- if (pci_find_bus(pci_domain_nr(bus),
- max+i+1))
+ if (pci_bus_exists(pci_domain_nr(bus), max+i+1))
break;
while (parent->parent) {
if ((!pcibios_assign_all_busses()) &&
@@ -930,6 +931,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)

out:
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl);
+ pci_bus_put(child);

return max;
}
@@ -1691,10 +1693,11 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
if (!b)
return NULL;

- b2 = pci_find_bus(pci_domain_nr(b), bus);
+ b2 = pci_get_bus(pci_domain_nr(b), bus);
if (b2) {
/* If we already got to this bus through a different bridge, ignore it */
dev_dbg(&b2->dev, "bus already known\n");
+ pci_bus_put(b2);
goto err_out;
}

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 16abaaa..9a3e3f7 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1317,12 +1317,10 @@ static int __init pci_bus_get_depth(struct pci_bus *bus)
}
static int __init pci_get_max_depth(void)
{
- int depth = 0;
+ int ret, depth = 0;
struct pci_bus *bus;

- list_for_each_entry(bus, &pci_root_buses, node) {
- int ret;
-
+ for_each_pci_root_bus(bus) {
ret = pci_bus_get_depth(bus);
if (ret > depth)
depth = ret;
@@ -1423,11 +1421,11 @@ again:
add_list = &realloc_head;
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
__pci_bus_size_bridges(bus, add_list);

/* Depth last, allocate resources and update the hardware. */
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
__pci_bus_assign_resources(bus, add_list, &fail_head);
if (add_list)
BUG_ON(!list_empty(add_list));
@@ -1480,11 +1478,11 @@ again:

enable_and_dump:
/* Depth last, update the hardware. */
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pci_enable_bridges(bus);

/* dump the resource on buses */
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pci_bus_dump_resources(bus);
}

diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 966abc6..816cf94 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -522,7 +522,7 @@ static int pcifront_rescan_root(struct pcifront_device *pdev,
dev_info(&pdev->xdev->dev, "Rescanning PCI Frontend Bus %04x:%02x\n",
domain, bus);

- b = pci_find_bus(domain, bus);
+ b = pci_get_bus(domain, bus);
if (!b)
/* If the bus is unknown, create it. */
return pcifront_scan_root(pdev, domain, bus);
@@ -534,6 +534,7 @@ static int pcifront_rescan_root(struct pcifront_device *pdev,

/* Create SysFS and notify udev of the devices. Aka: "going live" */
pci_bus_add_devices(b);
+ pci_bus_put(b);

return err;
}
--
1.8.1.2

2013-05-14 16:52:33

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 04/18] PCI, Alpha: use hotplug-safe iterators to walk PCI buses

Enhance Alpha architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/alpha/kernel/pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index edb4e00..094cd58 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -305,7 +305,7 @@ pcibios_claim_console_setup(void)
{
struct pci_bus *b;

- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_claim_one_bus(b);
}

--
1.8.1.2

2013-05-14 16:52:50

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 05/18] PCI, FRV: use hotplug-safe iterators to walk PCI buses

Enhance FRV architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: David Howells <[email protected]>
Cc: Jiang Liu <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: [email protected]
---
arch/frv/mb93090-mb00/pci-frv.c | 5 ++++-
arch/frv/mb93090-mb00/pci-vdk.c | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index c281217..48ee89a 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -188,8 +188,11 @@ static void __init pcibios_assign_resources(void)

void __init pcibios_resource_survey(void)
{
+ struct pci_bus *bus;
+
DBG("PCI: Allocating resources\n");
- pcibios_allocate_bus_resources(&pci_root_buses);
+ for_each_pci_root_bus(bus)
+ pcibios_allocate_bus_resources(&bus->children);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
pcibios_assign_resources();
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index 0aa35f0..f1d6c16 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -234,7 +234,7 @@ static void __init pcibios_fixup_peer_bridges(void)
return;
printk("PCI: Peer bridge fixup\n");
for (n=0; n <= pcibios_last_bus; n++) {
- if (pci_find_bus(0, n))
+ if (pci_bus_exists(0, n))
continue;
bus.number = n;
bus.ops = pci_root_ops;
--
1.8.1.2

2013-05-14 16:52:58

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 06/18] PCI, IA64: use hotplug-safe iterators to walk PCI buses

Enhance IA64 architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Fenghua Yu <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
arch/ia64/hp/common/sba_iommu.c | 2 +-
arch/ia64/sn/kernel/io_common.c | 2 +-
arch/ia64/sn/pci/tioca_provider.c | 3 ++-
3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index bcda5b2..6faf241 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -2156,7 +2156,7 @@ sba_init(void)
#ifdef CONFIG_PCI
{
struct pci_bus *b = NULL;
- while ((b = pci_find_next_bus(b)) != NULL)
+ for_each_pci_root_bus(b)
sba_connect_bus(b);
}
#endif
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 11f2275..87d8d8f 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -530,7 +530,7 @@ sn_io_late_init(void)
* info from the PROM).
*/
bus = NULL;
- while ((bus = pci_find_next_bus(bus)) != NULL) {
+ for_each_pci_root_bus(bus) {
bussoft = SN_PCIBUS_BUSSOFT(bus);
nasid = NASID_GET(bussoft->bs_base);
cnode = nasid_to_cnodeid(nasid);
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index a70b11f..cd8c0fb 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -624,7 +624,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
nasid_to_cnodeid(tioca_common->ca_closest_nasid);
tioca_common->ca_kernel_private = (u64) tioca_kern;

- bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment,
+ bus = pci_get_bus(tioca_common->ca_common.bs_persist_segment,
tioca_common->ca_common.bs_persist_busnum);
BUG_ON(!bus);
tioca_kern->ca_devices = &bus->devices;
@@ -632,6 +632,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
/* init GART */

if (tioca_gart_init(tioca_kern) < 0) {
+ pci_bus_put(bus);
kfree(tioca_kern);
kfree(tioca_common);
return NULL;
--
1.8.1.2

2013-05-14 16:53:07

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 08/18] PCI, mn10300: use hotplug-safe iterators to walk PCI buses

Enhance mn10300 architecture specific code to use hotplug-safe
iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: David Howells <[email protected]>
Cc: Koichi Yasutake <[email protected]>
Cc: [email protected]
---
arch/mn10300/unit-asb2305/pci-asb2305.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c
index c4e2e79..88c0c52 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.c
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.c
@@ -207,8 +207,11 @@ fs_initcall(pcibios_assign_resources);

void __init pcibios_resource_survey(void)
{
+ struct pci_bus *bus;
+
DBG("PCI: Allocating resources\n");
- pcibios_allocate_bus_resources(&pci_root_buses);
+ for_each_pci_root_bus(bus)
+ pcibios_allocate_bus_resources(&bus->children);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
}
--
1.8.1.2

2013-05-14 16:53:13

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 09/18] PCI, PPC: use hotplug-safe iterators to walk PCI buses

Enhance PPC architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Bjorn Helgaas <[email protected]>
Cc: Gavin Shan <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Bill Pemberton <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
arch/powerpc/kernel/pci-common.c | 4 ++--
arch/powerpc/kernel/pci_64.c | 13 +++++--------
2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fa12ae4..26fca09 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1400,7 +1400,7 @@ void __init pcibios_resource_survey(void)
struct pci_bus *b;

/* Allocate and assign resources */
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_allocate_bus_resources(b);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
@@ -1410,7 +1410,7 @@ void __init pcibios_resource_survey(void)
* bus available resources to avoid allocating things on top of them
*/
if (!pci_has_flag(PCI_PROBE_ONLY)) {
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_reserve_legacy_regions(b);
}

diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 51a133a..a41c6dd 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -208,7 +208,6 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
unsigned long in_devfn)
{
struct pci_controller* hose;
- struct list_head *ln;
struct pci_bus *bus = NULL;
struct device_node *hose_node;

@@ -229,18 +228,16 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
/* That syscall isn't quite compatible with PCI domains, but it's
* used on pre-domains setup. We return the first match
*/
-
- for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
- bus = pci_bus_b(ln);
- if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+ for_each_pci_root_bus(bus)
+ if (in_bus >= bus->number && in_bus <= bus->busn_res.end &&
+ bus->dev.of_node)
break;
- bus = NULL;
- }
- if (bus == NULL || bus->dev.of_node == NULL)
+ if (bus == NULL)
return -ENODEV;

hose_node = bus->dev.of_node;
hose = PCI_DN(hose_node)->phb;
+ pci_bus_put(bus);

switch (which) {
case IOBASE_BRIDGE_NUMBER:
--
1.8.1.2

2013-05-14 16:53:33

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 13/18] PCI, DRM: use hotplug-safe iterators to walk PCI buses

Enhance DRM drvier to use hotplug-safe iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: David Airlie <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/gpu/drm/drm_fops.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 13fdcd1..04f3bcd 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -357,9 +357,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
pci_dev_put(pci_dev);
}
if (!dev->hose) {
- struct pci_bus *b = pci_bus_b(pci_root_buses.next);
- if (b)
+ struct pci_bus *b = pci_get_next_root_bus(NULL);
+ if (b) {
dev->hose = b->sysdata;
+ pci_bus_put(b);
+ }
}
}
#endif
--
1.8.1.2

2013-05-14 16:53:40

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 14/18] PCI, EDAC: use hotplug-safe PCI bus iterators to walk PCI buses

Enhance EDAC drviers to use hotplug-safe iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Doug Thompson <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/edac/i7core_edac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 0ec3e95..39d5823 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1296,7 +1296,7 @@ static unsigned i7core_pci_lastbus(void)
int last_bus = 0, bus;
struct pci_bus *b = NULL;

- while ((b = pci_find_next_bus(b)) != NULL) {
+ for_each_pci_root_bus(b)
bus = b->number;
edac_dbg(0, "Found bus %d\n", bus);
if (bus > last_bus)
--
1.8.1.2

2013-05-14 16:53:45

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 15/18] PCI, via-camera: use hotplug-safe iterators to walk PCI buses

Enhance via-camera drviers to use hotplug-safe iterators to walk
PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Daniel Drake <[email protected]>
Cc: Jonathan Corbet <[email protected]>
Cc: Javier Martin <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/media/platform/via-camera.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c
index b051c4a..ef10136 100644
--- a/drivers/media/platform/via-camera.c
+++ b/drivers/media/platform/via-camera.c
@@ -1284,7 +1284,8 @@ static struct video_device viacam_v4l_template = {

static bool viacam_serial_is_enabled(void)
{
- struct pci_bus *pbus = pci_find_bus(0, 0);
+ struct pci_bus *pbus = pci_get_bus(0, 0);
+ bool ret = false;
u8 cbyte;

if (!pbus)
@@ -1292,18 +1293,21 @@ static bool viacam_serial_is_enabled(void)
pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
VIACAM_SERIAL_CREG, &cbyte);
if ((cbyte & VIACAM_SERIAL_BIT) == 0)
- return false; /* Not enabled */
+ goto out; /* Not enabled */
if (override_serial == 0) {
printk(KERN_NOTICE "Via camera: serial port is enabled, " \
"refusing to load.\n");
printk(KERN_NOTICE "Specify override_serial=1 to force " \
"module loading.\n");
- return true;
+ ret = true;
+ goto out;
}
printk(KERN_NOTICE "Via camera: overriding serial port\n");
pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
- return false;
+out:
+ pci_bus_put(pbus);
+ return ret;
}

static struct ov7670_config sensor_cfg = {
--
1.8.1.2

2013-05-14 16:53:52

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 16/18] PCI, iommu: use hotplug-safe iterators to walk PCI buses

Enhance iommu drviers to use hotplug-safe iterators to walk
PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Joerg Roedel <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Donald Dutile <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: "Li, Zhen-Hua" <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/iommu/amd_iommu.c | 4 +++-
drivers/iommu/dmar.c | 6 ++++--
2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index e046d7a..d6fdf94 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -357,6 +357,7 @@ static int init_iommu_group(struct device *dev)
struct iommu_dev_data *dev_data;
struct iommu_group *group;
struct pci_dev *dma_pdev;
+ struct pci_bus *b = NULL;
int ret;

group = iommu_group_get(dev);
@@ -393,7 +394,7 @@ static int init_iommu_group(struct device *dev)
* the alias. Be careful to also test the parent device if
* we think the alias is the root of the group.
*/
- bus = pci_find_bus(0, alias >> 8);
+ b = bus = pci_find_bus(0, alias >> 8);
if (!bus)
goto use_group;

@@ -413,6 +414,7 @@ static int init_iommu_group(struct device *dev)
dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
use_pdev:
ret = use_pdev_iommu_group(dma_pdev, dev);
+ pci_bus_put(b);
pci_dev_put(dma_pdev);
return ret;
use_group:
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e5cdaf8..5bb3cdc 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -67,12 +67,12 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
struct pci_dev **dev, u16 segment)
{
- struct pci_bus *bus;
+ struct pci_bus *b, *bus;
struct pci_dev *pdev = NULL;
struct acpi_dmar_pci_path *path;
int count;

- bus = pci_find_bus(segment, scope->bus);
+ b = bus = pci_find_bus(segment, scope->bus);
path = (struct acpi_dmar_pci_path *)(scope + 1);
count = (scope->length - sizeof(struct acpi_dmar_device_scope))
/ sizeof(struct acpi_dmar_pci_path);
@@ -97,6 +97,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
count --;
bus = pdev->subordinate;
}
+ pci_bus_put(b);
+
if (!pdev) {
pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n",
segment, scope->bus, path->dev, path->fn);
--
1.8.1.2

2013-05-14 16:53:57

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 17/18] PCI, eeepc-laptop: use hotplug-safe iterators to walk PCI buses

Enhance eeepc-laptop drvier to use hotplug-safe iterators to walk
PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Corentin Chary <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/platform/x86/eeepc-laptop.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 5d26e70..6291b4f 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -759,7 +759,7 @@ static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
{
int ret = -ENOMEM;
- struct pci_bus *bus = pci_find_bus(0, 1);
+ struct pci_bus *bus = pci_get_bus(0, 1);

if (!bus) {
pr_err("Unable to find wifi PCI bus\n");
@@ -787,6 +787,8 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
goto error_register;
}

+ pci_bus_put(bus);
+
return 0;

error_register:
@@ -795,6 +797,7 @@ error_info:
kfree(eeepc->hotplug_slot);
eeepc->hotplug_slot = NULL;
error_slot:
+ pci_bus_put(bus);
return ret;
}

--
1.8.1.2

2013-05-14 16:54:03

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 18/18] PCI, asus-wmi: use hotplug-safe iterators to walk PCI buses

Enhance asus-wmi drvier to use hotplug-safe iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Corentin Chary <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
drivers/platform/x86/asus-wmi.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index c11b242..f92db4c 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -596,7 +596,7 @@ static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
static void asus_rfkill_hotplug(struct asus_wmi *asus)
{
struct pci_dev *dev;
- struct pci_bus *bus;
+ struct pci_bus *bus = NULL;
bool blocked;
bool absent;
u32 l;
@@ -611,7 +611,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus)
rfkill_set_sw_state(asus->wlan.rfkill, blocked);

if (asus->hotplug_slot) {
- bus = pci_find_bus(0, 1);
+ bus = pci_get_bus(0, 1);
if (!bus) {
pr_warn("Unable to find PCI bus 1?\n");
goto out_unlock;
@@ -657,6 +657,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus)

out_unlock:
mutex_unlock(&asus->hotplug_lock);
+ pci_bus_put(bus);
}

static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
@@ -748,7 +749,7 @@ static void asus_hotplug_work(struct work_struct *work)
static int asus_setup_pci_hotplug(struct asus_wmi *asus)
{
int ret = -ENOMEM;
- struct pci_bus *bus = pci_find_bus(0, 1);
+ struct pci_bus *bus = pci_get_bus(0, 1);

if (!bus) {
pr_err("Unable to find wifi PCI bus\n");
@@ -782,6 +783,7 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus)
pr_err("Unable to register hotplug slot - %d\n", ret);
goto error_register;
}
+ pci_bus_put(bus);

return 0;

@@ -793,6 +795,7 @@ error_info:
error_slot:
destroy_workqueue(asus->hotplug_workqueue);
error_workqueue:
+ pci_bus_put(bus);
return ret;
}

--
1.8.1.2

2013-05-14 16:53:30

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 12/18] PCI, ACPI: use hotplug-safe iterators to walk PCI buses

Enhance ACPI reset drvier to use hotplug-safe iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Len Brown <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/acpi/reboot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index a6c77e8b..532dd6d 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -33,7 +33,7 @@ void acpi_reboot(void)
switch (rr->space_id) {
case ACPI_ADR_SPACE_PCI_CONFIG:
/* The reset register can only live on bus 0. */
- bus0 = pci_find_bus(0, 0);
+ bus0 = pci_get_bus(0, 0);
if (!bus0)
return;
/* Form PCI device/function pair. */
@@ -43,6 +43,7 @@ void acpi_reboot(void)
/* Write the value that resets us. */
pci_bus_write_config_byte(bus0, devfn,
(rr->address & 0xffff), reset_value);
+ pci_bus_put(bus0);
break;

case ACPI_ADR_SPACE_SYSTEM_MEMORY:
--
1.8.1.2

2013-05-14 16:53:25

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 11/18] PCI, x86: use hotplug-safe iterators to walk PCI buses

Enhance x86 architecture specific code to use hotplug-safe iterators
to walk PCI buses.

In other words, replace pci_find_bus(), pci_find_next_bus() and
pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
and pci_get_next_root_bus() etc.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: [email protected]
Cc: Myron Stowe <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Matthew Garrett <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: [email protected]
---
arch/x86/pci/acpi.c | 3 ++-
arch/x86/pci/common.c | 3 ++-
arch/x86/pci/i386.c | 9 ++++-----
arch/x86/pci/irq.c | 2 +-
arch/x86/pci/legacy.c | 2 +-
5 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 3e72425..b972f04 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -526,7 +526,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
* Maybe the desired pci bus has been already scanned. In such case
* it is unnecessary to scan the pci bus with the given domain,busnum.
*/
- bus = pci_find_bus(domain, busnum);
+ bus = pci_get_bus(domain, busnum);
if (bus) {
/*
* If the desired bus exits, the content of bus->sysdata will
@@ -534,6 +534,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
*/
memcpy(bus->sysdata, sd, sizeof(*sd));
kfree(info);
+ pci_bus_put(bus);
} else {
probe_pci_root_info(info, device, busnum, domain);

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 305c68b..51cc1be 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -460,8 +460,9 @@ struct pci_bus *pcibios_scan_root(int busnum)
{
struct pci_bus *bus = NULL;

- while ((bus = pci_find_next_bus(bus)) != NULL) {
+ for_each_pci_root_bus(bus) {
if (bus->number == busnum) {
+ pci_bus_put(bus);
/* Already scanned */
return bus;
}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 94919e3..6481d25 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -343,7 +343,7 @@ static int __init pcibios_assign_resources(void)
struct pci_bus *bus;

if (!(pci_probe & PCI_ASSIGN_ROMS))
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pcibios_allocate_rom_resources(bus);

pci_assign_unassigned_resources();
@@ -371,12 +371,11 @@ void __init pcibios_resource_survey(void)

DBG("PCI: Allocating resources\n");

- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pcibios_allocate_bus_resources(bus);
-
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pcibios_allocate_resources(bus, 0);
- list_for_each_entry(bus, &pci_root_buses, node)
+ for_each_pci_root_bus(bus)
pcibios_allocate_resources(bus, 1);

e820_reserve_resources_late();
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 372e9b8..65898f6 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -137,7 +137,7 @@ static void __init pirq_peer_trick(void)
}
for (i = 1; i < 256; i++) {
int node;
- if (!busmap[i] || pci_find_bus(0, i))
+ if (!busmap[i] || pci_bus_exists(0, i))
continue;
node = get_mp_bus_to_node(i);
if (pci_scan_bus_on_node(i, &pci_root_ops, node))
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 4db96fb..1fb7922 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -40,7 +40,7 @@ void pcibios_scan_specific_bus(int busn)
long node;
u32 l;

- if (pci_find_bus(0, busn))
+ if (pci_bus_exists(0, busn))
return;

node = get_mp_bus_to_node(busn);
--
1.8.1.2

2013-05-14 16:53:20

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 10/18] PCI, SPARC: use hotplug-safe iterators to walk PCI buses

Enhance SPARC architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Jiang Liu <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
arch/sparc/kernel/pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index e5871fb..235208d8 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -995,9 +995,9 @@ static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)

static int __init of_pci_slot_init(void)
{
- struct pci_bus *pbus = NULL;
+ struct pci_bus *pbus;

- while ((pbus = pci_find_next_bus(pbus)) != NULL) {
+ for_each_pci_root_bus(pbus) {
struct device_node *node;

if (pbus->self) {
--
1.8.1.2

2013-05-14 16:53:02

by Jiang Liu

[permalink] [raw]
Subject: [RFC PATCH v2, part 2 07/18] PCI, Microblaze: use hotplug-safe iterators to walk PCI buses

Enhance Microblaze architecture specific code to use hotplug-safe
iterators to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Hiroo MATSUMOTO <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
arch/microblaze/pci/pci-common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 9ea521e..14bd8e1 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1318,7 +1318,7 @@ void __init pcibios_resource_survey(void)
/* Allocate and assign resources. If we re-assign everything, then
* we skip the allocate phase
*/
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_allocate_bus_resources(b);

pcibios_allocate_resources(0);
@@ -1328,7 +1328,7 @@ void __init pcibios_resource_survey(void)
* the low IO area and the VGA memory area if they intersect the
* bus available resources to avoid allocating things on top of them
*/
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_reserve_legacy_regions(b);

/* Now proceed to assigning things that were left unassigned */
--
1.8.1.2

2013-05-14 17:05:20

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 01/18] PCI: introduce hotplug-safe PCI bus iterators

On Wed, May 15, 2013 at 12:51:45AM +0800, Jiang Liu wrote:
> +EXPORT_SYMBOL(pci_bus_exists);

EXPORT_SYMBOL_GPL()? Same for the other new exports?

thanks,

greg k-h

2013-05-14 18:55:19

by Yinghai Lu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 02/18] PCI, core: use hotplug-safe iterators to walk PCI buses

On Tue, May 14, 2013 at 9:51 AM, Jiang Liu <[email protected]> wrote:
> Enhance PCI core to use hotplug-safe iterators to walk PCI buses.
>
> In other words, replace pci_find_bus(), pci_find_next_bus() and
> pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
> and pci_get_next_root_bus() etc.

good changes.

Acked-by: Yinghai Lu <[email protected]>

2013-05-14 18:56:25

by Yinghai Lu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 01/18] PCI: introduce hotplug-safe PCI bus iterators

On Tue, May 14, 2013 at 9:51 AM, Jiang Liu <[email protected]> wrote:
> Introduce hotplug-safe PCI bus iterators as below, which hold a
> reference on the returned PCI bus object.
> bool pci_bus_exists(int domain, int busnr);
> struct pci_bus *pci_get_bus(int domain, int busnr);
> struct pci_bus *pci_get_next_bus(struct pci_bus *from);
> struct pci_bus *pci_get_next_root_bus(struct pci_bus *from);
> #define for_each_pci_bus(b) for (b = NULL; (b = pci_get_next_bus(b)); )
> #define for_each_pci_root_bus(b) \
> for (b = NULL; (b = pci_get_next_root_bus(b)); )
>
> The long-term goal is to remove hotplug-unsafe pci_find_bus(),
> pci_find_next_bus() and the global pci_root_buses list.
>
> These new interfaces may be a littler slower than existing interfaces,
> but it should be acceptable because they are not used on hot paths.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Cc: [email protected]
> Cc: [email protected]

Acked-by: Yinghai Lu <[email protected]>

2013-05-14 18:57:27

by Yinghai Lu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 03/18] PCI, hotplug: use hotplug-safe iterators to walk PCI buses

On Tue, May 14, 2013 at 9:51 AM, Jiang Liu <[email protected]> wrote:
> Enhance PCI hotplug drivers to use hotplug-safe iterators to walk
> PCI buses.
>
> In other words, replace pci_find_bus(), pci_find_next_bus() and
> pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
> and pci_get_next_root_bus() etc.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Cc: Yinghai Lu <[email protected]>
> Cc: Jiri Kosina <[email protected]>
> Cc: Masanari Iida <[email protected]>
> Cc: "Rafael J. Wysocki" <[email protected]>
> Cc: Toshi Kani <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/pci/hotplug-pci.c | 2 +-
> drivers/pci/hotplug/ibmphp_core.c | 8 +++++---
> drivers/pci/hotplug/ibmphp_ebda.c | 8 ++++++--
> drivers/pci/hotplug/sgi_hotplug.c | 3 ++-
> drivers/pci/hotplug/shpchp_sysfs.c | 2 +-
> 5 files changed, 15 insertions(+), 8 deletions(-)

Acked-by: Yinghai Lu <[email protected]>

2013-05-14 18:59:23

by Yinghai Lu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 11/18] PCI, x86: use hotplug-safe iterators to walk PCI buses

On Tue, May 14, 2013 at 9:51 AM, Jiang Liu <[email protected]> wrote:
> Enhance x86 architecture specific code to use hotplug-safe iterators
> to walk PCI buses.
>
> In other words, replace pci_find_bus(), pci_find_next_bus() and
> pci_root_buses with pci_bus_exists(), pci_get_bus(), pci_get_next_bus()
> and pci_get_next_root_bus() etc.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Ingo Molnar <[email protected]>
> Cc: "H. Peter Anvin" <[email protected]>
> Cc: [email protected]
> Cc: Myron Stowe <[email protected]>
> Cc: Yijing Wang <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>
> Cc: Matthew Garrett <[email protected]>
> Cc: Yinghai Lu <[email protected]>
> Cc: [email protected]
> ---
> arch/x86/pci/acpi.c | 3 ++-
> arch/x86/pci/common.c | 3 ++-
> arch/x86/pci/i386.c | 9 ++++-----
> arch/x86/pci/irq.c | 2 +-
> arch/x86/pci/legacy.c | 2 +-
> 5 files changed, 10 insertions(+), 9 deletions(-)

Acked-by: Yinghai Lu <[email protected]>

2013-05-14 20:19:41

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 12/18] PCI, ACPI: use hotplug-safe iterators to walk PCI buses

On Wednesday, May 15, 2013 12:51:56 AM Jiang Liu wrote:
> Enhance ACPI reset drvier to use hotplug-safe iterators to walk PCI buses.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Cc: Len Brown <[email protected]>
> Cc: "Rafael J. Wysocki" <[email protected]>
> Cc: [email protected]
> Cc: [email protected]

Acked-by: Rafael J. Wysocki <[email protected]>

> ---
> drivers/acpi/reboot.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
> index a6c77e8b..532dd6d 100644
> --- a/drivers/acpi/reboot.c
> +++ b/drivers/acpi/reboot.c
> @@ -33,7 +33,7 @@ void acpi_reboot(void)
> switch (rr->space_id) {
> case ACPI_ADR_SPACE_PCI_CONFIG:
> /* The reset register can only live on bus 0. */
> - bus0 = pci_find_bus(0, 0);
> + bus0 = pci_get_bus(0, 0);
> if (!bus0)
> return;
> /* Form PCI device/function pair. */
> @@ -43,6 +43,7 @@ void acpi_reboot(void)
> /* Write the value that resets us. */
> pci_bus_write_config_byte(bus0, devfn,
> (rr->address & 0xffff), reset_value);
> + pci_bus_put(bus0);
> break;
>
> case ACPI_ADR_SPACE_SYSTEM_MEMORY:
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

2013-05-14 22:13:49

by Donald Dutile

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 16/18] PCI, iommu: use hotplug-safe iterators to walk PCI buses

On 05/14/2013 12:52 PM, Jiang Liu wrote:
> Enhance iommu drviers to use hotplug-safe iterators to walk
> PCI buses.
>
> Signed-off-by: Jiang Liu<[email protected]>
> Cc: Joerg Roedel<[email protected]>
> Cc: Ingo Molnar<[email protected]>
> Cc: Donald Dutile<[email protected]>
> Cc: Hannes Reinecke<[email protected]>
> Cc: "Li, Zhen-Hua"<[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/iommu/amd_iommu.c | 4 +++-
> drivers/iommu/dmar.c | 6 ++++--
> 2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index e046d7a..d6fdf94 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -357,6 +357,7 @@ static int init_iommu_group(struct device *dev)
> struct iommu_dev_data *dev_data;
> struct iommu_group *group;
> struct pci_dev *dma_pdev;
> + struct pci_bus *b = NULL;
> int ret;
>
> group = iommu_group_get(dev);
> @@ -393,7 +394,7 @@ static int init_iommu_group(struct device *dev)
> * the alias. Be careful to also test the parent device if
> * we think the alias is the root of the group.
> */
> - bus = pci_find_bus(0, alias>> 8);
> + b = bus = pci_find_bus(0, alias>> 8);
> if (!bus)
> goto use_group;
>
> @@ -413,6 +414,7 @@ static int init_iommu_group(struct device *dev)
> dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
> use_pdev:
> ret = use_pdev_iommu_group(dma_pdev, dev);
> + pci_bus_put(b);
pci_find_bus() does a pci_bus_put() after the pci_get_bus();
is this needed, or did you mean to make the above patch pci_get_bus() ?

> pci_dev_put(dma_pdev);
> return ret;
> use_group:
> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> index e5cdaf8..5bb3cdc 100644
> --- a/drivers/iommu/dmar.c
> +++ b/drivers/iommu/dmar.c
> @@ -67,12 +67,12 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
> static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
> struct pci_dev **dev, u16 segment)
> {
> - struct pci_bus *bus;
> + struct pci_bus *b, *bus;
> struct pci_dev *pdev = NULL;
> struct acpi_dmar_pci_path *path;
> int count;
>
> - bus = pci_find_bus(segment, scope->bus);
> + b = bus = pci_find_bus(segment, scope->bus);
> path = (struct acpi_dmar_pci_path *)(scope + 1);
> count = (scope->length - sizeof(struct acpi_dmar_device_scope))
> / sizeof(struct acpi_dmar_pci_path);
> @@ -97,6 +97,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
> count --;
> bus = pdev->subordinate;
> }
> + pci_bus_put(b);
ditto.

> +
> if (!pdev) {
> pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n",
> segment, scope->bus, path->dev, path->fn);

2013-05-15 00:44:09

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 09/18] PCI, PPC: use hotplug-safe iterators to walk PCI buses

On Wed, 2013-05-15 at 00:51 +0800, Jiang Liu wrote:
> Enhance PPC architecture specific code to use hotplug-safe iterators
> to walk PCI buses.

I was about to ack it but then I saw:

> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
> index 51a133a..a41c6dd 100644
> --- a/arch/powerpc/kernel/pci_64.c
> +++ b/arch/powerpc/kernel/pci_64.c
> @@ -208,7 +208,6 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
> unsigned long in_devfn)
> {
> struct pci_controller* hose;
> - struct list_head *ln;
> struct pci_bus *bus = NULL;
> struct device_node *hose_node;
>
> @@ -229,18 +228,16 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
> /* That syscall isn't quite compatible with PCI domains, but it's
> * used on pre-domains setup. We return the first match
> */
> -
> - for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
> - bus = pci_bus_b(ln);
> - if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
> + for_each_pci_root_bus(bus)
> + if (in_bus >= bus->number && in_bus <= bus->busn_res.end &&
> + bus->dev.of_node)
> break;
> - bus = NULL;
> - }
> - if (bus == NULL || bus->dev.of_node == NULL)
> + if (bus == NULL)
> return -ENODEV;

You just removed the NULL check for the of_node field...

> hose_node = bus->dev.of_node;
> hose = PCI_DN(hose_node)->phb;

Which is dereferrenced here.

> + pci_bus_put(bus);

On the other hand, the whole thing can probably be using
pci_bus_to_host() instead.... the above code is bitrotted.

> switch (which) {
> case IOBASE_BRIDGE_NUMBER:

Cheeers,
Ben.

2013-05-15 14:43:08

by Jiang Liu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 01/18] PCI: introduce hotplug-safe PCI bus iterators

On 05/15/2013 01:05 AM, Greg Kroah-Hartman wrote:
> On Wed, May 15, 2013 at 12:51:45AM +0800, Jiang Liu wrote:
>> +EXPORT_SYMBOL(pci_bus_exists);
> EXPORT_SYMBOL_GPL()? Same for the other new exports?
>
> thanks,
>
> greg k-h
Sure, will change to EXPORT_SYMBOL_GPL in next version.
Thanks for review!
Gerry

2013-05-15 14:51:20

by Jiang Liu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 01/18] PCI: introduce hotplug-safe PCI bus iterators

On 05/15/2013 01:05 AM, Greg Kroah-Hartman wrote:
> On Wed, May 15, 2013 at 12:51:45AM +0800, Jiang Liu wrote:
>> +EXPORT_SYMBOL(pci_bus_exists);
> EXPORT_SYMBOL_GPL()? Same for the other new exports?
>
> thanks,
>
> greg k-h
Hi Greg,
Only pci_root_buses from drivers/pci/search.c is exported as GPL,
all other functions from that file are exported as EXPORT_SYMBOL().
So should we keep those new interfaces as EXPORT_SYMBOL() too?
Thanks,
Gerry

2013-05-15 15:08:00

by Jiang Liu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 09/18] PCI, PPC: use hotplug-safe iterators to walk PCI buses

On 05/15/2013 07:30 AM, Benjamin Herrenschmidt wrote:
> On Wed, 2013-05-15 at 00:51 +0800, Jiang Liu wrote:
>> Enhance PPC architecture specific code to use hotplug-safe iterators
>> to walk PCI buses.
> I was about to ack it but then I saw:
>
>> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
>> index 51a133a..a41c6dd 100644
>> --- a/arch/powerpc/kernel/pci_64.c
>> +++ b/arch/powerpc/kernel/pci_64.c
>> @@ -208,7 +208,6 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
>> unsigned long in_devfn)
>> {
>> struct pci_controller* hose;
>> - struct list_head *ln;
>> struct pci_bus *bus = NULL;
>> struct device_node *hose_node;
>>
>> @@ -229,18 +228,16 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
>> /* That syscall isn't quite compatible with PCI domains, but it's
>> * used on pre-domains setup. We return the first match
>> */
>> -
>> - for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
>> - bus = pci_bus_b(ln);
>> - if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
>> + for_each_pci_root_bus(bus)
>> + if (in_bus >= bus->number && in_bus <= bus->busn_res.end &&
>> + bus->dev.of_node)
>> break;
>> - bus = NULL;
>> - }
>> - if (bus == NULL || bus->dev.of_node == NULL)
>> + if (bus == NULL)
>> return -ENODEV;
> You just removed the NULL check for the of_node field...
Hi Benjamin,
Thanks for review.
I just moved the "bus->dev.of_node == NULL" into the above
for_each_pci_root_bus()
loop:)
Will send you another version according to your suggestion to use
pci_bus_to_host()
to simplify the code.
Regards!
Gerry

>
>> hose_node = bus->dev.of_node;
>> hose = PCI_DN(hose_node)->phb;
> Which is dereferrenced here.
>
>> + pci_bus_put(bus);
> On the other hand, the whole thing can probably be using
> pci_bus_to_host() instead.... the above code is bitrotted.
>
>> switch (which) {
>> case IOBASE_BRIDGE_NUMBER:
>
> Cheeers,
> Ben.
>
>

2013-05-15 15:17:31

by Jiang Liu

[permalink] [raw]
Subject: PCI, PPC: use hotplug-safe iterators to walk PCI buses

Enhance PPC architecture specific code to use hotplug-safe iterators
to walk PCI buses.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Gavin Shan <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Bill Pemberton <[email protected]>
Cc: Yinghai Lu <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
Hi Benjamin,
How about this version? Use pci_bus_to_host() instead
to simplify code.
Regards!
Gerry
---
arch/powerpc/kernel/pci-common.c | 4 ++--
arch/powerpc/kernel/pci_64.c | 22 ++++++++--------------
2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fa12ae4..26fca09 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1400,7 +1400,7 @@ void __init pcibios_resource_survey(void)
struct pci_bus *b;

/* Allocate and assign resources */
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_allocate_bus_resources(b);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
@@ -1410,7 +1410,7 @@ void __init pcibios_resource_survey(void)
* bus available resources to avoid allocating things on top of them
*/
if (!pci_has_flag(PCI_PROBE_ONLY)) {
- list_for_each_entry(b, &pci_root_buses, node)
+ for_each_pci_root_bus(b)
pcibios_reserve_legacy_regions(b);
}

diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 51a133a..8bea231 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -207,10 +207,8 @@ void pcibios_setup_phb_io_space(struct pci_controller *hose)
long sys_pciconfig_iobase(long which, unsigned long in_bus,
unsigned long in_devfn)
{
- struct pci_controller* hose;
- struct list_head *ln;
- struct pci_bus *bus = NULL;
- struct device_node *hose_node;
+ struct pci_controller* hose = NULL;
+ struct pci_bus *bus;

/* Argh ! Please forgive me for that hack, but that's the
* simplest way to get existing XFree to not lockup on some
@@ -229,19 +227,15 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
/* That syscall isn't quite compatible with PCI domains, but it's
* used on pre-domains setup. We return the first match
*/
-
- for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
- bus = pci_bus_b(ln);
- if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+ for_each_pci_root_bus(bus)
+ if (in_bus >= bus->number && in_bus <= bus->busn_res.end) {
+ hose = pci_bus_to_host(bus);
+ pci_bus_put(bus);
break;
- bus = NULL;
- }
- if (bus == NULL || bus->dev.of_node == NULL)
+ }
+ if (hose == NULL)
return -ENODEV;

- hose_node = bus->dev.of_node;
- hose = PCI_DN(hose_node)->phb;
-
switch (which) {
case IOBASE_BRIDGE_NUMBER:
return (long)hose->first_busno;
--
1.8.1.2

2013-05-15 15:36:53

by Jiang Liu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 16/18] PCI, iommu: use hotplug-safe iterators to walk PCI buses

On 05/15/2013 06:13 AM, Don Dutile wrote:
> On 05/14/2013 12:52 PM, Jiang Liu wrote:
>> Enhance iommu drviers to use hotplug-safe iterators to walk
>> PCI buses.
>>
>> Signed-off-by: Jiang Liu<[email protected]>
>> Cc: Joerg Roedel<[email protected]>
>> Cc: Ingo Molnar<[email protected]>
>> Cc: Donald Dutile<[email protected]>
>> Cc: Hannes Reinecke<[email protected]>
>> Cc: "Li, Zhen-Hua"<[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> ---
>> drivers/iommu/amd_iommu.c | 4 +++-
>> drivers/iommu/dmar.c | 6 ++++--
>> 2 files changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
>> index e046d7a..d6fdf94 100644
>> --- a/drivers/iommu/amd_iommu.c
>> +++ b/drivers/iommu/amd_iommu.c
>> @@ -357,6 +357,7 @@ static int init_iommu_group(struct device *dev)
>> struct iommu_dev_data *dev_data;
>> struct iommu_group *group;
>> struct pci_dev *dma_pdev;
>> + struct pci_bus *b = NULL;
>> int ret;
>>
>> group = iommu_group_get(dev);
>> @@ -393,7 +394,7 @@ static int init_iommu_group(struct device *dev)
>> * the alias. Be careful to also test the parent device if
>> * we think the alias is the root of the group.
>> */
>> - bus = pci_find_bus(0, alias>> 8);
>> + b = bus = pci_find_bus(0, alias>> 8);
>> if (!bus)
>> goto use_group;
>>
>> @@ -413,6 +414,7 @@ static int init_iommu_group(struct device *dev)
>> dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
>> use_pdev:
>> ret = use_pdev_iommu_group(dma_pdev, dev);
>> + pci_bus_put(b);
> pci_find_bus() does a pci_bus_put() after the pci_get_bus();
> is this needed, or did you mean to make the above patch pci_get_bus() ?
Hi Don,
Thanks for review!
My fault, I should use pci_get_bus() instead, will fix it in next
version.
Regards!
Gerry


>
>> pci_dev_put(dma_pdev);
>> return ret;
>> use_group:
>> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
>> index e5cdaf8..5bb3cdc 100644
>> --- a/drivers/iommu/dmar.c
>> +++ b/drivers/iommu/dmar.c
>> @@ -67,12 +67,12 @@ static void __init dmar_register_drhd_unit(struct
>> dmar_drhd_unit *drhd)
>> static int __init dmar_parse_one_dev_scope(struct
>> acpi_dmar_device_scope *scope,
>> struct pci_dev **dev, u16 segment)
>> {
>> - struct pci_bus *bus;
>> + struct pci_bus *b, *bus;
>> struct pci_dev *pdev = NULL;
>> struct acpi_dmar_pci_path *path;
>> int count;
>>
>> - bus = pci_find_bus(segment, scope->bus);
>> + b = bus = pci_find_bus(segment, scope->bus);
>> path = (struct acpi_dmar_pci_path *)(scope + 1);
>> count = (scope->length - sizeof(struct acpi_dmar_device_scope))
>> / sizeof(struct acpi_dmar_pci_path);
>> @@ -97,6 +97,8 @@ static int __init dmar_parse_one_dev_scope(struct
>> acpi_dmar_device_scope *scope,
>> count --;
>> bus = pdev->subordinate;
>> }
>> + pci_bus_put(b);
> ditto.
>
>> +
>> if (!pdev) {
>> pr_warn("Device scope device [%04x:%02x:%02x.%02x] not
>> found\n",
>> segment, scope->bus, path->dev, path->fn);
>

2013-05-22 04:14:47

by Gu Zheng

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 14/18] PCI, EDAC: use hotplug-safe PCI bus iterators to walk PCI buses

On 05/15/2013 12:51 AM, Jiang Liu wrote:

> Enhance EDAC drviers to use hotplug-safe iterators to walk PCI buses.
>
> Signed-off-by: Jiang Liu <[email protected]>
> Cc: Mauro Carvalho Chehab <[email protected]>
> Cc: Doug Thompson <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/edac/i7core_edac.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
> index 0ec3e95..39d5823 100644
> --- a/drivers/edac/i7core_edac.c
> +++ b/drivers/edac/i7core_edac.c
> @@ -1296,7 +1296,7 @@ static unsigned i7core_pci_lastbus(void)
> int last_bus = 0, bus;
> struct pci_bus *b = NULL;
>
> - while ((b = pci_find_next_bus(b)) != NULL) {
> + for_each_pci_root_bus(b)

missing the "{":
+ for_each_pci_root_bus(b) {

> bus = b->number;
> edac_dbg(0, "Found bus %d\n", bus);
> if (bus > last_bus)

2013-05-25 15:19:35

by Jiang Liu

[permalink] [raw]
Subject: Re: [RFC PATCH v2, part 2 14/18] PCI, EDAC: use hotplug-safe PCI bus iterators to walk PCI buses

On Wed 22 May 2013 12:12:19 PM CST, Gu Zheng wrote:
> On 05/15/2013 12:51 AM, Jiang Liu wrote:
>
>> Enhance EDAC drviers to use hotplug-safe iterators to walk PCI buses.
>>
>> Signed-off-by: Jiang Liu <[email protected]>
>> Cc: Mauro Carvalho Chehab <[email protected]>
>> Cc: Doug Thompson <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> ---
>> drivers/edac/i7core_edac.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
>> index 0ec3e95..39d5823 100644
>> --- a/drivers/edac/i7core_edac.c
>> +++ b/drivers/edac/i7core_edac.c
>> @@ -1296,7 +1296,7 @@ static unsigned i7core_pci_lastbus(void)
>> int last_bus = 0, bus;
>> struct pci_bus *b = NULL;
>>
>> - while ((b = pci_find_next_bus(b)) != NULL) {
>> + for_each_pci_root_bus(b)
>
> missing the "{":
> + for_each_pci_root_bus(b) {
Hi Zheng,
Thanks for review! Will fix it in next version.
Regards!
Gerry

>
>> bus = b->number;
>> edac_dbg(0, "Found bus %d\n", bus);
>> if (bus > last_bus)
>
>