PCI: Look for unassigned resources on per-bus basis
authorYinghai Lu <yinghai@kernel.org>
Mon, 22 Jul 2013 21:37:13 +0000 (14:37 -0700)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 25 Jul 2013 18:35:02 +0000 (12:35 -0600)
When CONFIG_PCI_REALLOC_ENABLE_AUTO=y, pci_realloc_detect() looks at PCI
devices to see if any have SR-IOV resources that need to be assigned.  If
it finds any, it turns on automatic resource reallocation.

This patch changes pci_realloc_detect() so it uses pci_walk_bus() on
each root bus instead of using for_each_pci_dev().  This is a step
toward doing reallocation on a per-bus basis, so we can do it for
a hot-added host bridge.

[bhelgaas: changelog, rename callback to iov_resources_unassigned(), use
boolean for "unassigned"]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/setup-bus.c

index cb6bcbb..20c09bd 100644 (file)
@@ -1359,30 +1359,44 @@ static bool __init pci_realloc_enabled(void)
        return pci_realloc_enable >= user_enabled;
 }
 
-static void __init pci_realloc_detect(void)
-{
 #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO)
-       struct pci_dev *dev = NULL;
+static int __init iov_resources_unassigned(struct pci_dev *dev, void *data)
+{
+       int i;
+       bool *unassigned = data;
 
-       if (pci_realloc_enable != undefined)
-               return;
+       for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) {
+               struct resource *r = &dev->resource[i];
 
-       for_each_pci_dev(dev) {
-               int i;
+               /* Not assigned or rejected by kernel? */
+               if (r->flags && !r->start) {
+                       *unassigned = true;
+                       return 1; /* return early from pci_walk_bus() */
+               }
+       }
 
-               for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) {
-                       struct resource *r = &dev->resource[i];
+       return 0;
+}
 
-                       /* Not assigned, or rejected by kernel ? */
-                       if (r->flags && !r->start) {
-                               pci_realloc_enable = auto_enabled;
+static void  __init pci_realloc_detect(void)
+{
+       bool unassigned = false;
+       struct pci_bus *bus;
 
-                               return;
-                       }
+       if (pci_realloc_enable != undefined)
+               return;
+
+       list_for_each_entry(bus, &pci_root_buses, node) {
+               pci_walk_bus(bus, iov_resources_unassigned, &unassigned);
+               if (unassigned) {
+                       pci_realloc_enable = auto_enabled;
+                       return;
                }
        }
-#endif
 }
+#else
+static void __init pci_realloc_detect(void) { }
+#endif
 
 /*
  * first try will not touch pci bridge res