aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@huawei.com>2013-06-22 19:01:35 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-06-22 19:01:35 -0400
commitd66ecb7220a70ec3f6c0e38e4af28fb8b25d31c6 (patch)
tree7fdc232881ed9685e94a2f8e17bc112ddd1c3f1e /drivers/pci/hotplug
parent94add0f82469fa3c4ff978d03a34da90813c819d (diff)
PCI / ACPI: Use boot-time resource allocation rules during hotplug
On x86 platforms, the kernel respects PCI resource assignments from the BIOS and only reassigns resources for unassigned BARs at boot time. However, with the ACPI-based hotplug (acpiphp), it ignores the BIOS' PCI resource assignments completely and reassigns all resources by itself. This causes differences in PCI resource allocation between boot time and runtime hotplug to occur, which is generally undesirable and sometimes actively breaks things. Namely, if there are enough resources, reassigning all PCI resources during runtime hotplug should work, but it may fail if the resources are constrained. This may happen, for instance, when some PCI devices with huge MMIO BARs are involved in the runtime hotplug operations, because the current PCI MMIO alignment algorithm may waste huge chunks of MMIO address space in those cases. On the Alexander's Sony VAIO VPCZ23A4R the BIOS allocates limited MMIO resources for the dock station which contains a device (graphics adapter) with a 256MB MMIO BAR. An attempt to reassign that during runtime hotplug causes the dock station MMIO window to be exhausted and acpiphp fails to allocate resources for the majority of devices on the dock station as a result. To prevent that from happening, modify acpiphp to follow the boot time resources allocation behavior so that the BIOS' resource assignments are respected during runtime hotplug too. [rjw: Changelog] References: https://bugzilla.kernel.org/show_bug.cgi?id=56531 Reported-and-tested-by: Alexander E. Patrakov <patrakov@gmail.com> Tested-by: Illya Klymov <xanf@xanf.me> Signed-off-by: Jiang Liu <jiang.liu@huawei.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Cc: 3.9+ <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 716aa93fff76..050b6f9abfd1 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -670,6 +670,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
670 struct pci_bus *bus = slot->bridge->pci_bus; 670 struct pci_bus *bus = slot->bridge->pci_bus;
671 struct acpiphp_func *func; 671 struct acpiphp_func *func;
672 int num, max, pass; 672 int num, max, pass;
673 LIST_HEAD(add_list);
673 674
674 if (slot->flags & SLOT_ENABLED) 675 if (slot->flags & SLOT_ENABLED)
675 goto err_exit; 676 goto err_exit;
@@ -694,13 +695,15 @@ static int __ref enable_device(struct acpiphp_slot *slot)
694 max = pci_scan_bridge(bus, dev, max, pass); 695 max = pci_scan_bridge(bus, dev, max, pass);
695 if (pass && dev->subordinate) { 696 if (pass && dev->subordinate) {
696 check_hotplug_bridge(slot, dev); 697 check_hotplug_bridge(slot, dev);
697 pci_bus_size_bridges(dev->subordinate); 698 pcibios_resource_survey_bus(dev->subordinate);
699 __pci_bus_size_bridges(dev->subordinate,
700 &add_list);
698 } 701 }
699 } 702 }
700 } 703 }
701 } 704 }
702 705
703 pci_bus_assign_resources(bus); 706 __pci_bus_assign_resources(bus, &add_list, NULL);
704 acpiphp_sanitize_bus(bus); 707 acpiphp_sanitize_bus(bus);
705 acpiphp_set_hpp_values(bus); 708 acpiphp_set_hpp_values(bus);
706 acpiphp_set_acpi_region(slot); 709 acpiphp_set_acpi_region(slot);