From 967260cdb13f9c0de3cf56e305b34eb363e41d5b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:15 -0700 Subject: [PATCH] PCI: Enable unassigned resource reallocation on per-bus basis pci_realloc_detect() turns on automatic resource allocation when it finds unassigned SR-IOV resources. Previously it did this on a global basis, so we enabled reallocation if any PCI device anywhere had an unassigned SR-IOV resource. This patch changes pci_realloc_detect() so it looks at a single bus, so we can do this when a host bridge is hot-added. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 42 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed1bd0cdf521..4aaa8d57443f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1354,9 +1354,9 @@ void __init pci_realloc_get_opt(char *str) else if (!strncmp(str, "on", 2)) pci_realloc_enable = user_enabled; } -static bool __init pci_realloc_enabled(void) +static bool __init pci_realloc_enabled(enum enable_type enable) { - return pci_realloc_enable >= user_enabled; + return enable >= user_enabled; } #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) @@ -1383,24 +1383,26 @@ static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) return 0; } -static void __init pci_realloc_detect(void) +static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, + enum enable_type enable_local) { bool unassigned = false; - struct pci_bus *bus; - if (pci_realloc_enable != undefined) - return; + if (enable_local != undefined) + return enable_local; - 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; - } - } + pci_walk_bus(bus, iov_resources_unassigned, &unassigned); + if (unassigned) + return auto_enabled; + + return enable_local; } #else -static void __init pci_realloc_detect(void) { } +static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, + enum enable_type enable_local) +{ + return enable_local; +} #endif /* @@ -1422,10 +1424,12 @@ pci_assign_unassigned_resources(void) unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; int pci_try_num = 1; + enum enable_type enable_local = pci_realloc_enable; - /* don't realloc if asked to do so */ - pci_realloc_detect(); - if (pci_realloc_enabled()) { + list_for_each_entry(bus, &pci_root_buses, node) + enable_local = pci_realloc_detect(bus, enable_local); + + if (pci_realloc_enabled(enable_local)) { int max_depth = pci_get_max_depth(); pci_try_num = max_depth + 1; @@ -1457,9 +1461,9 @@ again: goto enable_and_dump; if (tried_times >= pci_try_num) { - if (pci_realloc_enable == undefined) + if (enable_local == undefined) printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); - else if (pci_realloc_enable == auto_enabled) + else if (enable_local == auto_enabled) printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); free_list(&fail_head);