Skip to content

Commit 67f9085

Browse files
ij-intelbjorn-helgaas
authored andcommitted
PCI: Allow relaxed bridge window tail sizing for optional resources
Commit 566f1dd ("PCI: Relax bridge window tail sizing rules") relaxed the bridge window requirements for non-optional size (size0) but pbus_size_mem() also handles optional sizes (IOV resources) using size1. This can manifest, e.g., as a failure to resize a BAR back to its original size after it was first shrunk when device has a VF BAR resource because the bridge window (size1) is enlarged beyond what is strictly required to fit the downstream resources. Allow using relaxed bridge window tail sizing rules also with the optional resources (size1) so that the remove/realloc cycle during BAR resize (smaller and back to the original size) does not fail unexpectedly due to increase in bridge window size demand. Also move add_align calculation to more logical place next to size1 assignment as they are strongly related to each other. Link: https://lore.kernel.org/r/20241216175632.4175-5-ilpo.jarvinen@linux.intel.com Fixes: 566f1dd ("PCI: Relax bridge window tail sizing rules") Reported-by: Michał Winiarski <michal.winiarski@intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Xiaochun Lee <lixc17@lenovo.com>
1 parent a55bf64 commit 67f9085

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/pci/setup-bus.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
11461146
min_align = calculate_mem_align(aligns, max_order);
11471147
min_align = max(min_align, win_align);
11481148
size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align);
1149-
add_align = max(min_align, add_align);
11501149

11511150
if (bus->self && size0 &&
11521151
!pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
@@ -1159,8 +1158,21 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
11591158
}
11601159

11611160
if (realloc_head && (add_size > 0 || children_add_size > 0)) {
1161+
add_align = max(min_align, add_align);
11621162
size1 = calculate_memsize(size, min_size, add_size, children_add_size,
11631163
resource_size(b_res), add_align);
1164+
1165+
if (bus->self && size1 &&
1166+
!pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
1167+
size1, add_align)) {
1168+
min_align = 1ULL << (max_order + __ffs(SZ_1M));
1169+
min_align = max(min_align, win_align);
1170+
size1 = calculate_memsize(size, min_size, add_size, children_add_size,
1171+
resource_size(b_res), win_align);
1172+
pci_info(bus->self,
1173+
"bridge window %pR to %pR requires relaxed alignment rules\n",
1174+
b_res, &bus->busn_res);
1175+
}
11641176
}
11651177

11661178
if (!size0 && !size1) {

0 commit comments

Comments
 (0)