Re: [BUG] PCIe bridge resource allocation creates invalid limit addresses after Secondary Bus Reset recovery

Ilpo Järvinen
2026-03-12T13:24:48Z

[-- Attachment #1: Type: text/plain, Size: 4629 bytes --]

On Thu, 12 Mar 2026, Shawn Jin wrote:

> After enabling more debugging messages for PCI subsystem, it shows the
> pref bridge window was shrunken by 1 at [ 796.604883].
>
> Again, this is the kernel 6.8. I'll test 6.19 later using openSUSE
> Tumbleweed. This time the realloc was on.

Hi,

First of all, many of the changes related to this additional resource
distribution do not really make sense to me.

There's one fix that tries to rectify to most gross wrongness in the
adjustment itself because it caused a regression (not yet applied):

https://lore.kernel.org/linux-pci/20260219153951.68869-1-ilpo.jarvinen@linux.intel.com/

It probably doesn't address the bug you see here though it may hide it.

> [ 796.604869] pcieport 0000:96:01.0: distributing available resources
> [ 796.604872] pci 0000:98:00.0: bridge window [mem 0x00100000-0x001fffff] extended by 0x0000000000100000
> [ 796.604876] pci 0000:99:00.0: bridge window [??? 0x00000000 flags 0x0] extended by 0x0000000000055555
> [ 796.604880] pci 0000:99:01.0: bridge window [mem 0x00100000-0x001fffff] shrunken by 0x00000000000aaaac
> [ 796.604883] pci 0000:99:01.0: bridge window [mem 0x800000000-0xfffffffff 64bit pref] shrunken by 0x0000000000000001
> [ 796.604886] pci 0000:99:02.0: bridge window [??? 0x00000000 flags 0x0] extended by 0x0000000000055555

Note how it's not just -1 that seems wrong, the other numbers too seem
non-round (to 1M) as well.

There seems to be a number of problems with this entire algorithm.

I think the -1 comes from remove_dev_resource() that is called for a
resource which does have !res->flags (+ res->start=res->end=0 ->
resource_size(res) == 1).

So could you please try the patch below.

Not that the fix makes everything okay IMO but perhaps it addresses this
particular case. It's not even clear to me how some of the cases with not
valid bridge windows should be dealt with while distributing the
additional memory between the bridges.

The 55555 cases probably come from align == 0 which makes
ALIGN_DOWN_IF_NONZERO() to produce non-aligning sizes. The fix patch below
might address it.

I don't (yet) understand how that aaaac came to be, I suppose it somehow
relates to this doing something unexpected so if you want to check that
out, it would be helpful:

align = pci_resource_alignment(bridge, res);
if (!resource_assigned(res) && align)
available[i].start = min(ALIGN(available[i].start, align),
available[i].end + 1);

Another option is remove_dev_resource() doing something that leads to it.

It might be worth adding debug traps for available[i] getting non-1M
aligned but it's not very clear to me how and where.

From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
Date: Thu, 12 Mar 2026 14:59:43 +0200
Subject: [PATCH 1/1] PCI: Skip not valid bridge windows while distributing
resources
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

pci_bus_distribute_available_resources() distributes available
resources between downstream bridges, however, it does not take
into account cases where a bridge window is not valid.

Skip touching bridge windows that are not valid.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/pci/setup-bus.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 61f769aaa2f6..4fcb5e0c44b4 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1868,6 +1868,9 @@ static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
{
resource_size_t size, align, tmp;

+ if (!res->flags)
+ return;
+
size = resource_size(res);
if (!size)
return;
@@ -1922,6 +1925,8 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,

available[i] = available_in[i];

+ if (!res->flags)
+ continue;
/*
* The alignment of this bridge is yet to be considered,
* hence it must be done now before extending its bridge
@@ -1993,6 +1998,8 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) {
res = pci_resource_n(dev, PCI_BRIDGE_RESOURCES + i);

+ if (!res->flags)
+ continue;
/*
* Make sure the split resource space is properly
* aligned for bridge windows (align it down to

base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
--
2.39.5