mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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>,
	linux-kernel@vger.kernel.org
Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Subject: [PATCH v5 11/14] PCI: Calculate bridge window with optional sizes from scratch
Date: Fri,  6 Nov 2026 15:43:32 +0200	[thread overview]
Message-ID: <20261106134341.39493-12-ilpo.jarvinen@linux.intel.com> (raw)
In-Reply-To: <20261106134341.39493-1-ilpo.jarvinen@linux.intel.com>

pbus_size_mem() calls __pbus_size_mem() to calculate minimum head
alignment and size the bridge window. A single pass in
__pbus_size_mem() attempts to calculate both size with only mandatory
resources and also with optional size using add_align and
children_add_size.

The discovered resource sizes are passed to calculate_head_align() but
that only makes one calculation with mandatory resources in mind. That
means the alignment requirement for the case with optional resources is
determined from the maximum alignment, not from the required minimum
alignment.

To make the calculation more consistent, remove add_align and
children_add_size parameters, and make the caller decide if optional
resources should be included or not. Then, pbus_size_mem() can just
make a second call to __pbus_size_mem() to recalculate the alignment
and size with optional sizes.

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

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a8915b2354ea..6623adfdde85 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1013,10 +1013,9 @@ static resource_size_t calculate_iosize(resource_size_t size,
 
 static resource_size_t calculate_memsize(resource_size_t size,
 					 resource_size_t min_size,
-					 resource_size_t children_add_size,
 					 resource_size_t align)
 {
-	size = max(size + children_add_size, min_size);
+	size = max(size, min_size);
 	return ALIGN(size, align);
 }
 
@@ -1208,19 +1207,21 @@ static resource_size_t calculate_head_align(resource_size_t *aligns,
  * Account an optional resource or the optional part of the resource in bridge
  * window size.
  *
- * Return: %true if the resource is entirely optional.
+ * Return: %true if the resource is skipped due to optionality.
  */
 static bool pbus_size_mem_optional(struct pci_dev *dev, int resno,
-				   resource_size_t align,
-				   struct list_head *realloc_head,
-				   resource_size_t *add_align,
-				   resource_size_t *children_add_size)
+				   resource_size_t *size,
+				   resource_size_t *align,
+				   bool add_optional,
+				   struct list_head *realloc_head)
 {
 	struct resource *res = pci_resource_n(dev, resno);
 	bool optional = pci_resource_is_optional(dev, resno);
-	resource_size_t r_size = resource_size(res);
 	struct pci_dev_resource *dev_res = NULL;
 
+	if (!add_optional)
+		return optional;
+
 	if (!realloc_head)
 		return false;
 
@@ -1232,8 +1233,8 @@ static bool pbus_size_mem_optional(struct pci_dev *dev, int resno,
 	if (pci_resource_is_bridge_win(resno)) {
 		dev_res = res_to_dev_res(realloc_head, res);
 		if (dev_res) {
-			*children_add_size += dev_res->add_size;
-			*add_align = max(*add_align, dev_res->min_align);
+			*size += dev_res->add_size;
+			*align = max(*align, dev_res->min_align);
 		}
 	}
 
@@ -1246,22 +1247,28 @@ static bool pbus_size_mem_optional(struct pci_dev *dev, int resno,
 	 * on the list.
 	 */
 	if (!dev_res)
-		pci_dev_res_add_to_list(realloc_head, dev, res, 0, align);
-	*children_add_size += r_size;
-	*add_align = max(align, *add_align);
+		pci_dev_res_add_to_list(realloc_head, dev, res, 0, *align);
 
-	return true;
+	return false;
 }
 
 /* Alignments from 1MB to 128TB */
 #define PCI_RES_MAX_ALIGN	SZ_128T
 #define PCI_RES_ALIGN_RANGE	(ilog2(PCI_RES_MAX_ALIGN) - ilog2(SZ_1M) + 1)
 
+/*
+ * Since bridge memory windows are always at least 1MB aligned, keep order
+ * from being negative for smaller resources.
+ */
+static int pci_align_to_order(resource_size_t align)
+{
+	return max_t(int, __ffs64(align) - __ffs(SZ_1M), 0);
+}
+
 static resource_size_t __pbus_size_mem(struct pci_bus *bus,
 				       struct resource *b_res,
 				       resource_size_t *head_align,
-				       resource_size_t *add_align,
-				       resource_size_t *children_add_size,
+				       bool add_optional,
 				       struct list_head *realloc_head)
 {
 	struct pci_dev *dev;
@@ -1288,13 +1295,7 @@ static resource_size_t __pbus_size_mem(struct pci_bus *bus,
 			align = pci_resource_alignment(dev, r);
 			if (!align)
 				goto bad_alignment;
-			/*
-			 * aligns[0] is for 1MB (since bridge memory
-			 * windows are always at least 1MB aligned), so
-			 * keep "order" from being negative for smaller
-			 * resources.
-			 */
-			order = max_t(int, __ffs64(align) - __ffs(SZ_1M), 0);
+			order = pci_align_to_order(align);
 			if (order >= ARRAY_SIZE(aligns)) {
 bad_alignment:
 				pci_warn(dev, "%s %pR: disabling; bad alignment %#llx\n",
@@ -1303,12 +1304,17 @@ static resource_size_t __pbus_size_mem(struct pci_bus *bus,
 				continue;
 			}
 
-			if (pbus_size_mem_optional(dev, i, align,
-						   realloc_head, add_align,
-						   children_add_size))
-				continue;
-
 			r_size = resource_size(r);
+			/*
+			 * This has side-effects on size so it should not be
+			 * called while the resource can still be rejected
+			 * (such as the order check above). As align could
+			 * have changed, the order has to be recalculated.
+			 */
+			if (pbus_size_mem_optional(dev, i, &r_size, &align,
+						   add_optional, realloc_head))
+				continue;
+			order = pci_align_to_order(align);
 			winsize += max(r_size, align);
 
 			/*
@@ -1352,7 +1358,6 @@ static void pbus_size_mem(struct pci_bus *bus, struct resource *b_res,
 			  struct list_head *realloc_head)
 {
 	resource_size_t min_align, win_align, size, size0, size1 = 0;
-	resource_size_t children_add_size = 0;
 	resource_size_t add_align = 0;
 
 	if (!b_res)
@@ -1363,20 +1368,19 @@ static void pbus_size_mem(struct pci_bus *bus, struct resource *b_res,
 		return;
 
 	win_align = pci_min_window_alignment(bus, b_res->flags);
-	size = __pbus_size_mem(bus, b_res, &min_align, &add_align,
-			       &children_add_size, realloc_head);
-	size0 = calculate_memsize(size, realloc_head ? 0 : add_size,
-				  0, win_align);
+	size = __pbus_size_mem(bus, b_res, &min_align, !realloc_head,
+			       realloc_head);
+	size0 = calculate_memsize(size, realloc_head ? 0 : add_size, win_align);
 
 	if (size0) {
 		resource_set_range(b_res, min_align, size0);
 		b_res->flags &= ~IORESOURCE_DISABLED;
 	}
 
-	if (realloc_head && (add_size > 0 || children_add_size > 0)) {
+	if (realloc_head) {
+		size = __pbus_size_mem(bus, b_res, &add_align, true, realloc_head);
 		add_align = max(min_align, add_align);
-		size1 = calculate_memsize(size, add_size, children_add_size,
-					  win_align);
+		size1 = calculate_memsize(size, add_size, win_align);
 	}
 
 	if (!size0 && !size1) {
-- 
2.47.3


  parent reply	other threads:[~2026-11-06 13:45 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 ` Ilpo Järvinen [this message]
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 ` [PATCH v5 13/14] PCI: Fix composite resource sizing Ilpo Järvinen
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-12-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=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®