]>
Commit | Line | Data |
---|---|---|
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | |
2 | From: Kai-Heng Feng <kai.heng.feng@canonical.com> | |
3 | Date: Tue, 13 Jul 2021 20:50:07 +0800 | |
4 | Subject: [PATCH] PCI: Reinstate "PCI: Coalesce host bridge contiguous | |
5 | apertures" | |
6 | MIME-Version: 1.0 | |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | Built-in graphics on HP EliteDesk 805 G6 doesn't work because graphics | |
11 | can't get the BAR it needs: | |
12 | pci_bus 0000:00: root bus resource [mem 0x10020200000-0x100303fffff window] | |
13 | pci_bus 0000:00: root bus resource [mem 0x10030400000-0x100401fffff window] | |
14 | ||
15 | pci 0000:00:08.1: bridge window [mem 0xd2000000-0xd23fffff] | |
16 | pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100401fffff 64bit pref] | |
17 | pci 0000:00:08.1: can't claim BAR 15 [mem 0x10030000000-0x100401fffff 64bit pref]: no compatible bridge window | |
18 | pci 0000:00:08.1: [mem 0x10030000000-0x100401fffff 64bit pref] clipped to [mem 0x10030000000-0x100303fffff 64bit pref] | |
19 | pci 0000:00:08.1: bridge window [mem 0x10030000000-0x100303fffff 64bit pref] | |
20 | pci 0000:07:00.0: can't claim BAR 0 [mem 0x10030000000-0x1003fffffff 64bit pref]: no compatible bridge window | |
21 | pci 0000:07:00.0: can't claim BAR 2 [mem 0x10040000000-0x100401fffff 64bit pref]: no compatible bridge window | |
22 | ||
23 | However, the root bus has two contiguous apertures that can contain the | |
24 | child resource requested. | |
25 | ||
26 | Coalesce contiguous apertures so we can allocate from the entire contiguous | |
27 | region. | |
28 | ||
29 | This is the second take of commit 65db04053efe ("PCI: Coalesce host | |
30 | bridge contiguous apertures"). The original approach sorts the apertures | |
31 | by address, but that makes NVMe stop working on QEMU ppc:sam460ex: | |
32 | PCI host bridge to bus 0002:00 | |
33 | pci_bus 0002:00: root bus resource [io 0x0000-0xffff] | |
34 | pci_bus 0002:00: root bus resource [mem 0xd80000000-0xdffffffff] (bus address [0x80000000-0xffffffff]) | |
35 | pci_bus 0002:00: root bus resource [mem 0xc0ee00000-0xc0eefffff] (bus address [0x00000000-0x000fffff]) | |
36 | ||
37 | After the offending commit: | |
38 | PCI host bridge to bus 0002:00 | |
39 | pci_bus 0002:00: root bus resource [io 0x0000-0xffff] | |
40 | pci_bus 0002:00: root bus resource [mem 0xc0ee00000-0xc0eefffff] (bus address [0x00000000-0x000fffff]) | |
41 | pci_bus 0002:00: root bus resource [mem 0xd80000000-0xdffffffff] (bus address [0x80000000-0xffffffff]) | |
42 | ||
43 | Since the apertures on HP EliteDesk 805 G6 are already in ascending | |
44 | order, doing a precautious sorting is not necessary. | |
45 | ||
46 | Remove the sorting part to avoid the regression on ppc:sam460ex. | |
47 | ||
48 | Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212013 | |
49 | Cc: Guenter Roeck <linux@roeck-us.net> | |
50 | Suggested-by: Bjorn Helgaas <bhelgaas@google.com> | |
51 | Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> | |
52 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
53 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
54 | --- | |
55 | drivers/pci/probe.c | 33 ++++++++++++++++++++++++++++----- | |
56 | 1 file changed, 28 insertions(+), 5 deletions(-) | |
57 | ||
58 | diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c | |
59 | index d9fc02a71baa..3459f460dbd8 100644 | |
60 | --- a/drivers/pci/probe.c | |
61 | +++ b/drivers/pci/probe.c | |
62 | @@ -883,11 +883,11 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus) | |
63 | static int pci_register_host_bridge(struct pci_host_bridge *bridge) | |
64 | { | |
65 | struct device *parent = bridge->dev.parent; | |
66 | - struct resource_entry *window, *n; | |
67 | + struct resource_entry *window, *next, *n; | |
68 | struct pci_bus *bus, *b; | |
69 | - resource_size_t offset; | |
70 | + resource_size_t offset, next_offset; | |
71 | LIST_HEAD(resources); | |
72 | - struct resource *res; | |
73 | + struct resource *res, *next_res; | |
74 | char addr[64], *fmt; | |
75 | const char *name; | |
76 | int err; | |
77 | @@ -970,11 +970,34 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) | |
78 | if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE) | |
79 | dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n"); | |
80 | ||
81 | + /* Coalesce contiguous windows */ | |
82 | + resource_list_for_each_entry_safe(window, n, &resources) { | |
83 | + if (list_is_last(&window->node, &resources)) | |
84 | + break; | |
85 | + | |
86 | + next = list_next_entry(window, node); | |
87 | + offset = window->offset; | |
88 | + res = window->res; | |
89 | + next_offset = next->offset; | |
90 | + next_res = next->res; | |
91 | + | |
92 | + if (res->flags != next_res->flags || offset != next_offset) | |
93 | + continue; | |
94 | + | |
95 | + if (res->end + 1 == next_res->start) { | |
96 | + next_res->start = res->start; | |
97 | + res->flags = res->start = res->end = 0; | |
98 | + } | |
99 | + } | |
100 | + | |
101 | /* Add initial resources to the bus */ | |
102 | resource_list_for_each_entry_safe(window, n, &resources) { | |
103 | + offset = window->offset; | |
104 | + res = window->res; | |
105 | + if (!res->end) | |
106 | + continue; | |
107 | + | |
108 | list_move_tail(&window->node, &bridge->windows); | |
109 | - offset = window->offset; | |
110 | - res = window->res; | |
111 | ||
112 | if (res->flags & IORESOURCE_BUS) | |
113 | pci_bus_insert_busn_res(bus, bus->number, res->end); |