diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2021-11-05 11:28:45 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2021-11-05 11:28:45 -0500 |
commit | 1ebec13fc9e4ce93736658a95cf35f937e716b1b (patch) | |
tree | 13d8a2fa73a7eccf00825d782dd10de68f4a87fe /drivers/pci/probe.c | |
parent | 357cf0cdddceea974a7d32668a0df0d9f77055cb (diff) | |
parent | 7c3855c423b17f6ca211858afb0cef20569914c7 (diff) | |
download | linux-1ebec13fc9e4ce93736658a95cf35f937e716b1b.tar.gz linux-1ebec13fc9e4ce93736658a95cf35f937e716b1b.tar.bz2 linux-1ebec13fc9e4ce93736658a95cf35f937e716b1b.zip |
Merge branch 'pci/resource'
- Coalesce host bridge contiguous apertures to allow P2P bridge windows
that span several contiguous host bridge apertures (Kai-Heng Feng)
* pci/resource:
PCI: Coalesce host bridge contiguous apertures
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 240e4cf8c83e..78ca4cbebbb7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -883,11 +883,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; @@ -970,11 +970,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); |