]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: Fix resource double counting on remove & rescan
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 7 May 2024 10:25:16 +0000 (13:25 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 28 May 2024 16:14:14 +0000 (11:14 -0500)
pbus_size_mem() keeps the size of the optional resources in
children_add_size. When calculating the PCI bridge window size,
calculate_memsize() lower bounds size by old_size before adding
children_add_size and performing the window size alignment. This
results in double counting for the resources in children_add_size
because old_size may be based on the previous size of the bridge
window after it has already included children_add_size (that is,
size1 in pbus_size_mem() from an earlier invocation of that
function).

As a result, on repeated remove of the bus & rescan cycles the resource
size keeps increasing when children_add_size is non-zero as can be seen
from this extract:

  iomem0:  23fffd00000-23fffdfffff : PCI Bus 0000:03    # 1MiB
  iomem1:  20000000000-200001fffff : PCI Bus 0000:03    # 2MiB
  iomem2:  20000000000-200002fffff : PCI Bus 0000:03    # 3MiB
  iomem3:  20000000000-200003fffff : PCI Bus 0000:03    # 4MiB
  iomem4:  20000000000-200004fffff : PCI Bus 0000:03    # 5MiB

Solve the double counting by moving old_size check later in
calculate_memsize() so that children_add_size is already accounted for.

After the patch, the bridge window retains its size as expected:

  iomem0:  23fffd00000-23fffdfffff : PCI Bus 0000:03    # 1MiB
  iomem1:  20000000000-200000fffff : PCI Bus 0000:03    # 1MiB
  iomem2:  20000000000-200000fffff : PCI Bus 0000:03    # 1MiB

Fixes: a4ac9fea016f ("PCI : Calculate right add_size")
Link: https://lore.kernel.org/r/20240507102523.57320-2-ilpo.jarvinen@linux.intel.com
Tested-by: Lidong Wang <lidong.wang@intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/pci/setup-bus.c

index 909e6a7c3cc31b46e7d68c8cff2edbfd4b2420d6..141d6b31959be2c48d669d6fa7f80858b782415e 100644 (file)
@@ -829,11 +829,9 @@ static resource_size_t calculate_memsize(resource_size_t size,
                size = min_size;
        if (old_size == 1)
                old_size = 0;
-       if (size < old_size)
-               size = old_size;
 
-       size = ALIGN(max(size, add_size) + children_add_size, align);
-       return size;
+       size = max(size, add_size) + children_add_size;
+       return ALIGN(max(size, old_size), align);
 }
 
 resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus,