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>
This commit is contained in:
@@ -2015,6 +2015,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
the default.
|
the default.
|
||||||
off: Turn ECRC off
|
off: Turn ECRC off
|
||||||
on: Turn ECRC on.
|
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
|
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
|
||||||
Management.
|
Management.
|
||||||
|
@@ -3483,6 +3483,8 @@ static int __init pci_setup(char *str)
|
|||||||
pci_no_msi();
|
pci_no_msi();
|
||||||
} else if (!strcmp(str, "noaer")) {
|
} else if (!strcmp(str, "noaer")) {
|
||||||
pci_no_aer();
|
pci_no_aer();
|
||||||
|
} else if (!strncmp(str, "realloc", 7)) {
|
||||||
|
pci_realloc();
|
||||||
} else if (!strcmp(str, "nodomains")) {
|
} else if (!strcmp(str, "nodomains")) {
|
||||||
pci_no_domains();
|
pci_no_domains();
|
||||||
} else if (!strncmp(str, "cbiosize=", 9)) {
|
} else if (!strncmp(str, "cbiosize=", 9)) {
|
||||||
|
@@ -146,6 +146,8 @@ static inline void pci_no_msi(void) { }
|
|||||||
static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
|
static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void pci_realloc(void);
|
||||||
|
|
||||||
static inline int pci_no_d1d2(struct pci_dev *dev)
|
static inline int pci_no_d1d2(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
unsigned int parent_dstates = 0;
|
unsigned int parent_dstates = 0;
|
||||||
|
@@ -47,6 +47,13 @@ struct resource_list_x {
|
|||||||
(head)->next = NULL; \
|
(head)->next = NULL; \
|
||||||
} while (0)
|
} 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
|
* add_to_list() - add a new resource tracker to the list
|
||||||
* @head: Head of the list
|
* @head: Head of the list
|
||||||
@@ -1025,6 +1032,7 @@ static int __init pci_get_max_depth(void)
|
|||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first try will not touch pci bridge res
|
* first try will not touch pci bridge res
|
||||||
* second and later try will clear small leaf bridge res
|
* second and later try will clear small leaf bridge res
|
||||||
@@ -1068,6 +1076,13 @@ again:
|
|||||||
/* any device complain? */
|
/* any device complain? */
|
||||||
if (!head.next)
|
if (!head.next)
|
||||||
goto enable_and_dump;
|
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;
|
failed_type = 0;
|
||||||
for (list = head.next; list;) {
|
for (list = head.next; list;) {
|
||||||
failed_type |= list->flags;
|
failed_type |= list->flags;
|
||||||
|
Reference in New Issue
Block a user