5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai-Heng Feng kai.heng.feng@canonical.com
[ Upstream commit 65db04053efea3f3e412a7e0cc599962999c96b4 ]
Built-in graphics on HP EliteDesk 805 G6 doesn't work because graphics can't get the BAR it needs:
pci_bus 0000:00: root bus resource [mem 0x10020200000-0x100303fffff window] pci_bus 0000:00: root bus resource [mem 0x10030400000-0x100401fffff window]
pci 0000:00:08.1: bridge window [mem 0xd2000000-0xd23fffff] pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100401fffff 64bit pref] pci 0000:00:08.1: can't claim BAR 15 [mem 0x10030000000-0x100401fffff 64bit pref]: no compatible bridge window pci 0000:00:08.1: [mem 0x10030000000-0x100401fffff 64bit pref] clipped to [mem 0x10030000000-0x100303fffff 64bit pref] pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100303fffff 64bit pref] pci 0000:07:00.0: can't claim BAR 0 [mem 0x10030000000-0x1003fffffff 64bit pref]: no compatible bridge window pci 0000:07:00.0: can't claim BAR 2 [mem 0x10040000000-0x100401fffff 64bit pref]: no compatible bridge window
However, the root bus has two contiguous apertures that can contain the child resource requested.
Coalesce contiguous apertures so we can allocate from the entire contiguous region.
[bhelgaas: fold in https://lore.kernel.org/r/20210528170242.1564038-1-kai.heng.feng@canonical.c...] Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212013 Suggested-by: Bjorn Helgaas bhelgaas@google.com Link: https://lore.kernel.org/r/20210401131252.531935-1-kai.heng.feng@canonical.co... Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Stable-dep-of: 804443c1f278 ("PCI: Fix reference leak in pci_register_host_bridge()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/probe.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index be7973e249cd7..a2c53f6d1848a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -878,11 +878,11 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus) static int pci_register_host_bridge(struct pci_host_bridge *bridge) { struct device *parent = bridge->dev.parent; - struct resource_entry *window, *n; + struct resource_entry *window, *next, *n; struct pci_bus *bus, *b; - resource_size_t offset; + resource_size_t offset, next_offset; LIST_HEAD(resources); - struct resource *res; + struct resource *res, *next_res; char addr[64], *fmt; const char *name; int err; @@ -962,11 +962,34 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE) dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
+ /* Coalesce contiguous windows */ + resource_list_for_each_entry_safe(window, n, &resources) { + if (list_is_last(&window->node, &resources)) + break; + + next = list_next_entry(window, node); + offset = window->offset; + res = window->res; + next_offset = next->offset; + next_res = next->res; + + if (res->flags != next_res->flags || offset != next_offset) + continue; + + if (res->end + 1 == next_res->start) { + next_res->start = res->start; + res->flags = res->start = res->end = 0; + } + } + /* Add initial resources to the bus */ resource_list_for_each_entry_safe(window, n, &resources) { - list_move_tail(&window->node, &bridge->windows); offset = window->offset; res = window->res; + if (!res->end) + continue; + + list_move_tail(&window->node, &bridge->windows);
if (res->flags & IORESOURCE_BUS) pci_bus_insert_busn_res(bus, bus->number, res->end);