Commit b07f2ebc authored by Yinghai Lu's avatar Yinghai Lu Committed by Jesse Barnes
Browse files

PCI: add a PCI resource reallocation config option



Add a new config option, PCI_REALLOC_ENABLE_AUTO, which will
automatically try to re-allocate PCI resources if PCI_IOV support is
enabled and the SR-IOV resources are unassigned.  Behavior can still be
controlled using the pci=realloc= parameter.

-v2: According to Jesse, adding one CONFIG option for distribution to
     disable it or enable it.
-v3: update Kconfig text (jbarnes)

Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent eb572e7c
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,19 @@ config PCI_DEBUG


	  When in doubt, say N.
	  When in doubt, say N.


config PCI_REALLOC_ENABLE_AUTO
	bool "Enable PCI resource re-allocation detection"
	depends on PCI
	help
	  Say Y here if you want the PCI core to detect if PCI resource
	  re-allocation needs to be enabled. You can always use pci=realloc=on
          or pci=realloc=off to override it.  Note this feature is a no-op
          unless PCI_IOV support is also enabled; in that case it will
          automatically re-allocate PCI resources if SR-IOV BARs have not
          been allocated by the BIOS.

	  When in doubt, say N.

config PCI_STUB
config PCI_STUB
	tristate "PCI Stub driver"
	tristate "PCI Stub driver"
	depends on PCI
	depends on PCI
+28 −0
Original line number Original line Diff line number Diff line
@@ -1294,6 +1294,31 @@ static bool __init pci_realloc_enabled(void)
	return pci_realloc_enable >= user_enabled;
	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;

	if (pci_realloc_enable != undefined)
		return;

	for_each_pci_dev(dev) {
		int i;

		for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) {
			struct resource *r = &dev->resource[i];

			/* Not assigned, or rejected by kernel ? */
			if (r->flags && !r->start) {
				pci_realloc_enable = auto_enabled;

				return;
			}
		}
	}
#endif
}

/*
/*
 * 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
@@ -1315,6 +1340,7 @@ pci_assign_unassigned_resources(void)
	int pci_try_num = 1;
	int pci_try_num = 1;


	/* don't realloc if asked to do so */
	/* don't realloc if asked to do so */
	pci_realloc_detect();
	if (pci_realloc_enabled()) {
	if (pci_realloc_enabled()) {
		int max_depth = pci_get_max_depth();
		int max_depth = pci_get_max_depth();


@@ -1349,6 +1375,8 @@ again:
	if (tried_times >= pci_try_num) {
	if (tried_times >= pci_try_num) {
		if (pci_realloc_enable == undefined)
		if (pci_realloc_enable == undefined)
			printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n");
			printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n");
		else if (pci_realloc_enable == auto_enabled)
			printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n");


		free_list(&fail_head);
		free_list(&fail_head);
		goto enable_and_dump;
		goto enable_and_dump;