From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: "Maciej Grochowski" <Maciej.Grochowski@sony.com>,
"Geramy Loveless" <gloveless@jqluv.com>,
"Eric Auger" <eauger@redhat.com>,
"Alexey Fomenko" <alexey.fomenko@intel.com>,
"Bjorn Helgaas" <bhelgaas@google.com>,
linux-pci@vger.kernel.org,
"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Wilczyński" <kw@linux.com>,
"Mesih Kilinc" <Mesih.Kilinc@sony.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
linux-kernel@vger.kernel.org
Cc: Nikolas Joshua Britton <nbritton@exabit.io>
Subject: [PATCH v5 13/14] PCI: Fix composite resource sizing
Date: Fri, 6 Nov 2026 15:43:34 +0200 [thread overview]
Message-ID: <20261106134341.39493-14-ilpo.jarvinen@linux.intel.com> (raw)
In-Reply-To: <20261106134341.39493-1-ilpo.jarvinen@linux.intel.com>
The bridge window sizing algorithm aims to pack child resources back to
back. With composite child resources whose sizes are not a power of two,
back-to-back placement may not be possible. The non-aligning remainder
placement is limited because it must be adjacent to the rest of the
composite resource.
Add bridge window gap size calculation.
When there are only two resources and at least one of them is
composite, the gap end address aligns to meet the smaller of the two
alignment requirements. If there is only one composite resource, the
smaller alignment may be that of the composite resource.
Other combinations fall back to filling each resource's align sized
blocks fully. Sometimes, smaller size may be possible but due to how
sizing and assignment are made in different phases, it is not always
possible to predict where each resource is assigned. Thus, the sizing
has to play it safe.
Fixes: 9036bd0efcb6 ("PCI: Align head space better")
Reported-by: Bjorn Helgaas <bhelgaas@google.com>
Reported-by: Nikolas Joshua Britton <nbritton@exabit.io>
Link: https://lore.kernel.org/linux-pci/20260903063124.9316-1-nbritton@exabit.io/
Reported-by: Maciej Grochowski <Maciej.Grochowski@sony.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
I removed Bjorn's Tested-by tag as this patch has been through a major
rework.
There is one known failure mode (pointed out by AI review) with >= 3
resources, each with a different alignment requirement following a
certain pattern and the smallest align one must also be a composite
resource. Additional requirement is that the window must have an
odd-multiple start address.
While that corner case could be addressed by always forcing larger gaps
(at the cost of everyone paying the extra gap "tax"), I see no reason
to overengineer this for corner cases that might not occur in real
systems. If issues are reported, this can be revisited and perhaps more
complex fallback logic added (to avoid incurring the gap "tax"
unilaterally).
Adding the gap logic fixes known regressions seen in real systems, so
it is an important improvement even as is.
---
drivers/pci/setup-bus.c | 57 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b6be6cd16006..86c9557bc2fb 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1267,6 +1267,9 @@ static resource_size_t __pbus_size_mem(struct pci_bus *bus,
struct pci_dev *dev;
resource_size_t winsize = 0, win_align;
resource_size_t aligns[PCI_RES_ALIGN_RANGE] = {};
+ resource_size_t partial_blocks = 0, max_partial = 0;
+ unsigned int nonaligning = 0, rescount = 0;
+ resource_size_t remainders = 0, gap = 0;
int max_order = 0;
win_align = pci_min_window_alignment(bus, b_res->flags);
@@ -1277,7 +1280,7 @@ static resource_size_t __pbus_size_mem(struct pci_bus *bus,
pci_dev_for_each_resource(dev, r, i) {
const char *r_name = pci_resource_name(dev, i);
- resource_size_t r_size, align;
+ resource_size_t r_size, align, remainder;
if (!pdev_resources_assignable(dev) ||
!pdev_resource_should_fit(r))
@@ -1320,13 +1323,63 @@ static resource_size_t __pbus_size_mem(struct pci_bus *bus,
aligns[order] += align;
if (order > max_order)
max_order = order;
+
+ rescount++;
+
+ if (r_size <= align)
+ continue;
+ remainder = r_size - ALIGN_DOWN(r_size, align);
+ if (!remainder)
+ continue;
+
+ nonaligning++;
+ remainders += remainder;
+ partial_blocks += align;
+ max_partial = max(max_partial, align);
}
}
+ if (nonaligning && rescount == 2) {
+ resource_size_t second_align = max_partial;
+
+ /*
+ * With two resources having differing alignment
+ * requirements, the gap size can be optimized by aligning it
+ * only up to the smaller of the alignment requirements.
+ *
+ * This also allows two composite remainders to share the
+ * same block when the resources have the same alignment
+ * requirement which is common with multi-GPU setups where
+ * each bridge window contains a small BAR and a large BAR.
+ * The small BARs can share the same align block.
+ *
+ * As this sizing phase cannot influence resource assignment
+ * order and placement, this is only guaranteed to work with
+ * two non-aligning resources.
+ */
+ if (nonaligning == 2) {
+ second_align = partial_blocks - max_partial;
+ } else {
+ for (unsigned int i = 0; i < max_order; i++) {
+ if (!aligns[i])
+ continue;
+
+ second_align = min(second_align,
+ 1ULL << (i + __ffs(SZ_1M)));
+ break;
+ }
+ }
+
+ gap = ALIGN(remainders, second_align) - remainders;
+ } else if (nonaligning >= 2 ||
+ (nonaligning && rescount > nonaligning)) {
+ gap = partial_blocks - remainders;
+ }
+
*head_align = calculate_head_align(aligns, max_order);
*head_align = max(*head_align, win_align);
- return ALIGN(max(winsize, min_size), win_align);
+ return ALIGN(max(winsize + gap, min_size), win_align);
}
/**
--
2.47.3
next prev parent reply other threads:[~2026-11-06 13:46 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 13:43 [PATCH v5 00/14] PCI: Resource placement algorithm fixes Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 01/14] resource: Mark free space assigned Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 02/14] parisc/PCI: Clean up resource debug print & use dynamic debug Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 03/14] PCI: Don't size or assign disabled BARs Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 04/14] PCI: Use __ffs64() for resource_size_t typed align Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 05/14] PCI: Prevent zero align from reaching __ffs64() Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 06/14] linux/log2.h: Add 64-bit roundup/down_pow_of_two_u64() variants Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 07/14] PCI: Derive aligns[] array size in a define Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 08/14] PCI: Honor alignment overrides Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 09/14] PCI: Place resources to either edge of the window Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 10/14] PCI: Separate align/raw size calculation from pbus_size_mem() Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 11/14] PCI: Calculate bridge window with optional sizes from scratch Ilpo Järvinen
2026-11-06 13:43 ` [PATCH v5 12/14] PCI: Move size/align calculation fully into __pbus_size_mem() Ilpo Järvinen
2026-11-06 13:43 ` Ilpo Järvinen [this message]
2026-11-06 13:43 ` [PATCH v5 14/14] PCI: Add debug printing to window sizing Ilpo Järvinen
2026-11-06 15:26 ` [PATCH v5 00/14] PCI: Resource placement algorithm fixes Nikolas Joshua Britton
2026-11-06 16:43 ` Ilpo Järvinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261106134341.39493-14-ilpo.jarvinen@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=Maciej.Grochowski@sony.com \
--cc=Mesih.Kilinc@sony.com \
--cc=alexey.fomenko@intel.com \
--cc=bhelgaas@google.com \
--cc=eauger@redhat.com \
--cc=gloveless@jqluv.com \
--cc=kw@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=nbritton@exabit.io \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®