diff options
author | Yinghai Lu <yinghai@kernel.org> | 2013-07-22 17:37:15 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-07-25 14:35:03 -0400 |
commit | 967260cdb13f9c0de3cf56e305b34eb363e41d5b (patch) | |
tree | 7d977adb45121e6e10e9c412c0e8bb4ee424fdbc /drivers/pci | |
parent | fa216bf4dbe35e15044b90e7b51509768bab3d9a (diff) |
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 <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/setup-bus.c | 42 |
1 files 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) | |||
1354 | else if (!strncmp(str, "on", 2)) | 1354 | else if (!strncmp(str, "on", 2)) |
1355 | pci_realloc_enable = user_enabled; | 1355 | pci_realloc_enable = user_enabled; |
1356 | } | 1356 | } |
1357 | static bool __init pci_realloc_enabled(void) | 1357 | static bool __init pci_realloc_enabled(enum enable_type enable) |
1358 | { | 1358 | { |
1359 | return pci_realloc_enable >= user_enabled; | 1359 | return enable >= user_enabled; |
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) | 1362 | #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) | |||
1383 | return 0; | 1383 | return 0; |
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | static void __init pci_realloc_detect(void) | 1386 | static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, |
1387 | enum enable_type enable_local) | ||
1387 | { | 1388 | { |
1388 | bool unassigned = false; | 1389 | bool unassigned = false; |
1389 | struct pci_bus *bus; | ||
1390 | 1390 | ||
1391 | if (pci_realloc_enable != undefined) | 1391 | if (enable_local != undefined) |
1392 | return; | 1392 | return enable_local; |
1393 | 1393 | ||
1394 | list_for_each_entry(bus, &pci_root_buses, node) { | 1394 | pci_walk_bus(bus, iov_resources_unassigned, &unassigned); |
1395 | pci_walk_bus(bus, iov_resources_unassigned, &unassigned); | 1395 | if (unassigned) |
1396 | if (unassigned) { | 1396 | return auto_enabled; |
1397 | pci_realloc_enable = auto_enabled; | 1397 | |
1398 | return; | 1398 | return enable_local; |
1399 | } | ||
1400 | } | ||
1401 | } | 1399 | } |
1402 | #else | 1400 | #else |
1403 | static void __init pci_realloc_detect(void) { } | 1401 | static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, |
1402 | enum enable_type enable_local) | ||
1403 | { | ||
1404 | return enable_local; | ||
1405 | } | ||
1404 | #endif | 1406 | #endif |
1405 | 1407 | ||
1406 | /* | 1408 | /* |
@@ -1422,10 +1424,12 @@ pci_assign_unassigned_resources(void) | |||
1422 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1424 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1423 | IORESOURCE_PREFETCH; | 1425 | IORESOURCE_PREFETCH; |
1424 | int pci_try_num = 1; | 1426 | int pci_try_num = 1; |
1427 | enum enable_type enable_local = pci_realloc_enable; | ||
1428 | |||
1429 | list_for_each_entry(bus, &pci_root_buses, node) | ||
1430 | enable_local = pci_realloc_detect(bus, enable_local); | ||
1425 | 1431 | ||
1426 | /* don't realloc if asked to do so */ | 1432 | if (pci_realloc_enabled(enable_local)) { |
1427 | pci_realloc_detect(); | ||
1428 | if (pci_realloc_enabled()) { | ||
1429 | int max_depth = pci_get_max_depth(); | 1433 | int max_depth = pci_get_max_depth(); |
1430 | 1434 | ||
1431 | pci_try_num = max_depth + 1; | 1435 | pci_try_num = max_depth + 1; |
@@ -1457,9 +1461,9 @@ again: | |||
1457 | goto enable_and_dump; | 1461 | goto enable_and_dump; |
1458 | 1462 | ||
1459 | if (tried_times >= pci_try_num) { | 1463 | if (tried_times >= pci_try_num) { |
1460 | if (pci_realloc_enable == undefined) | 1464 | if (enable_local == undefined) |
1461 | printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); | 1465 | printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); |
1462 | else if (pci_realloc_enable == auto_enabled) | 1466 | else if (enable_local == auto_enabled) |
1463 | printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); | 1467 | printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); |
1464 | 1468 | ||
1465 | free_list(&fail_head); | 1469 | free_list(&fail_head); |