diff options
author | Ram Pai <linuxram@us.ibm.com> | 2011-07-07 11:19:10 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-07-08 15:49:20 -0700 |
commit | f483d3923dc3a6394c483e28ccb3fe700bdf399e (patch) | |
tree | ef487babd0ef104e1fa8323c23050d66096c0f3a | |
parent | a2fa83faf47b514ab947cea916d3691b66525073 (diff) | |
download | linux-stable-f483d3923dc3a6394c483e28ccb3fe700bdf399e.tar.gz linux-stable-f483d3923dc3a6394c483e28ccb3fe700bdf399e.tar.bz2 linux-stable-f483d3923dc3a6394c483e28ccb3fe700bdf399e.zip |
PCI: conditional resource-reallocation through kernel parameter pci=realloc
Multiple attempts to dynamically reallocate pci resources have
unfortunately lead to regressions. Though we continue to fix the
regressions and fine tune the dynamic-reallocation behavior, we have not
reached a acceptable state yet.
This patch provides a interim solution. It disables dynamic reallocation
by default, but adds the ability to enable it through pci=realloc kernel
command line parameter.
Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | drivers/pci/pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 15 |
4 files changed, 21 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fd248a318211..aa47be71df4c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2015,6 +2015,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the default. off: Turn ECRC off on: Turn ECRC on. + realloc reallocate PCI resources if allocations done by BIOS + are erroneous. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2c5b9b991279..692671b11667 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3483,6 +3483,8 @@ static int __init pci_setup(char *str) pci_no_msi(); } else if (!strcmp(str, "noaer")) { pci_no_aer(); + } else if (!strncmp(str, "realloc", 7)) { + pci_realloc(); } else if (!strcmp(str, "nodomains")) { pci_no_domains(); } else if (!strncmp(str, "cbiosize=", 9)) { diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 731e20265ace..3a39bf1f1e2c 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -146,6 +146,8 @@ static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif +extern void pci_realloc(void); + static inline int pci_no_d1d2(struct pci_dev *dev) { unsigned int parent_dstates = 0; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1e9e5a5b8c81..9995842e45b5 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -47,6 +47,13 @@ struct resource_list_x { (head)->next = NULL; \ } while (0) +int pci_realloc_enable = 0; +#define pci_realloc_enabled() pci_realloc_enable +void pci_realloc(void) +{ + pci_realloc_enable = 1; +} + /** * add_to_list() - add a new resource tracker to the list * @head: Head of the list @@ -1025,6 +1032,7 @@ static int __init pci_get_max_depth(void) return depth; } + /* * first try will not touch pci bridge res * second and later try will clear small leaf bridge res @@ -1068,6 +1076,13 @@ again: /* any device complain? */ if (!head.next) goto enable_and_dump; + + /* don't realloc if asked to do so */ + if (!pci_realloc_enabled()) { + free_list(resource_list_x, &head); + goto enable_and_dump; + } + failed_type = 0; for (list = head.next; list;) { failed_type |= list->flags; |