[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250822145605.18172-20-ilpo.jarvinen@linux.intel.com>
Date: Fri, 22 Aug 2025 17:56:00 +0300
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Andreas Larsson <andreas@...sler.com>,
Bjorn Helgaas <bhelgaas@...gle.com>,
"David S. Miller" <davem@...emloft.net>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
linux-m68k@...ts.linux-m68k.org,
linux-mips@...r.kernel.org,
linux-pci@...r.kernel.org,
sparclinux@...r.kernel.org,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Christian König <christian.koenig@....com>,
Yinghai Lu <yinghai@...nel.org>,
Igor Mammedov <imammedo@...hat.com>,
"Rafael J . Wysocki" <rafael@...nel.org>,
Jonathan Cameron <Jonathan.Cameron@...wei.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@....com>,
Krzysztof Wilczyński <kw@...ux.com>,
linux-kernel@...r.kernel.org
Cc: Michał Winiarski <michal.winiarski@...el.com>,
linuxppc-dev@...ts.ozlabs.org,
Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: [PATCH 19/24] PCI: Use pbus_select_window_for_type() during mem window sizing
__pci_bus_size_bridges() goes to great lengths of helping
pbus_size_mem() in which types it should put into a particular bridge
window, requiring passing up to three resource type into
pbus_size_mem().
Instead of having complex logic __pci_bus_size_bridges() and a
non-straightforward interface between those functions, use
pbus_select_window_for_type() and pbus_select_window() to find the
correct bridge window and compare if the resources belong to that
window.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
---
drivers/pci/setup-bus.c | 111 +++++++++-------------------------------
1 file changed, 24 insertions(+), 87 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 281ca5c73c97..28133a9c5f51 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1284,24 +1284,22 @@ static bool pbus_upstream_space_available(struct pci_bus *bus,
* pbus_size_mem() - Size the memory window of a given bus
*
* @bus: The bus
- * @mask: Mask the resource flag, then compare it with type
- * @type: The type of free resource from bridge
- * @type2: Second match type
- * @type3: Third match type
+ * @type: The type of bridge resource
* @min_size: The minimum memory window that must be allocated
* @add_size: Additional optional memory window
* @realloc_head: Track the additional memory window on this list
*
- * Calculate the size of the bus and minimal alignment which guarantees
- * that all child resources fit in this size.
+ * Calculate the size of the bus resource for @type and minimal alignment
+ * which guarantees that all child resources fit in this size.
*
- * Return -ENOSPC if there's no available bus resource of the desired
- * type. Otherwise, set the bus resource start/end to indicate the
- * required size, add things to realloc_head (if supplied), and return 0.
+ * Sets the bus resource start/end to indicate the required size if there an
+ * available unassigned bus resource of the desired @type.
+ *
+ * Adds optional resource requests to the @realloc_head list if it is
+ * supplied.
*/
-static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
- unsigned long type, unsigned long type2,
- unsigned long type3, resource_size_t min_size,
+static void pbus_size_mem(struct pci_bus *bus, unsigned long type,
+ resource_size_t min_size,
resource_size_t add_size,
struct list_head *realloc_head)
{
@@ -1309,19 +1307,18 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
resource_size_t min_align, win_align, align, size, size0, size1 = 0;
resource_size_t aligns[28]; /* Alignments from 1MB to 128TB */
int order, max_order;
- struct resource *b_res = find_bus_resource_of_type(bus,
- mask | IORESOURCE_PREFETCH, type);
+ struct resource *b_res = pbus_select_window_for_type(bus, type);
resource_size_t children_add_size = 0;
resource_size_t children_add_align = 0;
resource_size_t add_align = 0;
resource_size_t relaxed_align;
if (!b_res)
- return -ENOSPC;
+ return;
/* If resource is already assigned, nothing more to do */
if (b_res->parent)
- return 0;
+ return;
memset(aligns, 0, sizeof(aligns));
max_order = 0;
@@ -1338,11 +1335,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
if (!pdev_resources_assignable(dev) ||
!pdev_resource_should_fit(dev, r))
continue;
-
- if ((r->flags & mask) != type &&
- (r->flags & mask) != type2 &&
- (r->flags & mask) != type3)
+ if (b_res != pbus_select_window(bus, r))
continue;
+
r_size = resource_size(r);
/* Put SRIOV requested res to the optional list */
@@ -1428,7 +1423,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
b_res, &bus->busn_res);
b_res->flags |= IORESOURCE_DISABLED;
- return 0;
+ return;
}
resource_set_range(b_res, min_align, size0);
@@ -1441,7 +1436,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
(unsigned long long) (size1 - size0),
(unsigned long long) add_align);
}
- return 0;
}
unsigned long pci_cardbus_resource_alignment(struct resource *res)
@@ -1546,12 +1540,11 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
{
struct pci_dev *dev;
- unsigned long mask, prefmask, type2 = 0, type3 = 0;
resource_size_t additional_io_size = 0, additional_mmio_size = 0,
additional_mmio_pref_size = 0;
struct resource *pref;
struct pci_host_bridge *host;
- int hdr_type, ret;
+ int hdr_type;
list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_bus *b = dev->subordinate;
@@ -1601,71 +1594,15 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
additional_io_size, realloc_head);
- /*
- * If there's a 64-bit prefetchable MMIO window, compute
- * the size required to put all 64-bit prefetchable
- * resources in it.
- */
- mask = IORESOURCE_MEM;
- prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- if (pref && (pref->flags & IORESOURCE_MEM_64)) {
- prefmask |= IORESOURCE_MEM_64;
- ret = pbus_size_mem(bus, prefmask, prefmask,
- prefmask, prefmask,
- realloc_head ? 0 : additional_mmio_pref_size,
- additional_mmio_pref_size, realloc_head);
-
- /*
- * If successful, all non-prefetchable resources
- * and any 32-bit prefetchable resources will go in
- * the non-prefetchable window.
- */
- if (ret == 0) {
- mask = prefmask;
- type2 = prefmask & ~IORESOURCE_MEM_64;
- type3 = prefmask & ~IORESOURCE_PREFETCH;
- }
- }
-
- /*
- * If there is no 64-bit prefetchable window, compute the
- * size required to put all prefetchable resources in the
- * 32-bit prefetchable window (if there is one).
- */
- if (!type2) {
- prefmask &= ~IORESOURCE_MEM_64;
- ret = pbus_size_mem(bus, prefmask, prefmask,
- prefmask, prefmask,
- realloc_head ? 0 : additional_mmio_pref_size,
- additional_mmio_pref_size, realloc_head);
-
- /*
- * If successful, only non-prefetchable resources
- * will go in the non-prefetchable window.
- */
- if (ret == 0)
- mask = prefmask;
- else
- additional_mmio_size += additional_mmio_pref_size;
-
- type2 = type3 = IORESOURCE_MEM;
+ if (pref) {
+ pbus_size_mem(bus,
+ IORESOURCE_MEM | IORESOURCE_PREFETCH |
+ (pref->flags & IORESOURCE_MEM_64),
+ realloc_head ? 0 : additional_mmio_pref_size,
+ additional_mmio_pref_size, realloc_head);
}
- /*
- * Compute the size required to put everything else in the
- * non-prefetchable window. This includes:
- *
- * - all non-prefetchable resources
- * - 32-bit prefetchable resources if there's a 64-bit
- * prefetchable window or no prefetchable window at all
- * - 64-bit prefetchable resources if there's no prefetchable
- * window at all
- *
- * Note that the strategy in __pci_assign_resource() must match
- * that used here. Specifically, we cannot put a 32-bit
- * prefetchable resource in a 64-bit prefetchable window.
- */
- pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3,
+ pbus_size_mem(bus, IORESOURCE_MEM,
realloc_head ? 0 : additional_mmio_size,
additional_mmio_size, realloc_head);
break;
--
2.39.5
Powered by blists - more mailing lists