mirror of
https://github.com/torvalds/linux.git
synced 2025-11-04 18:49:34 +02:00
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 in __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@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/20250829131113.36754-20-ilpo.jarvinen@linux.intel.com
This commit is contained in:
parent
13016e15d5
commit
ae88d0b9c5
1 changed files with 24 additions and 87 deletions
|
|
@ -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
|
* pbus_size_mem() - Size the memory window of a given bus
|
||||||
*
|
*
|
||||||
* @bus: The bus
|
* @bus: The bus
|
||||||
* @mask: Mask the resource flag, then compare it with type
|
* @type: The type of bridge resource
|
||||||
* @type: The type of free resource from bridge
|
|
||||||
* @type2: Second match type
|
|
||||||
* @type3: Third match type
|
|
||||||
* @min_size: The minimum memory window that must be allocated
|
* @min_size: The minimum memory window that must be allocated
|
||||||
* @add_size: Additional optional memory window
|
* @add_size: Additional optional memory window
|
||||||
* @realloc_head: Track the additional memory window on this list
|
* @realloc_head: Track the additional memory window on this list
|
||||||
*
|
*
|
||||||
* Calculate the size of the bus and minimal alignment which guarantees
|
* Calculate the size of the bus resource for @type and minimal alignment
|
||||||
* that all child resources fit in this size.
|
* which guarantees that all child resources fit in this size.
|
||||||
*
|
*
|
||||||
* Return -ENOSPC if there's no available bus resource of the desired
|
* Set the bus resource start/end to indicate the required size if there an
|
||||||
* type. Otherwise, set the bus resource start/end to indicate the
|
* available unassigned bus resource of the desired @type.
|
||||||
* required size, add things to realloc_head (if supplied), and return 0.
|
*
|
||||||
|
* Add optional resource requests to the @realloc_head list if it is
|
||||||
|
* supplied.
|
||||||
*/
|
*/
|
||||||
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
static void pbus_size_mem(struct pci_bus *bus, unsigned long type,
|
||||||
unsigned long type, unsigned long type2,
|
resource_size_t min_size,
|
||||||
unsigned long type3, resource_size_t min_size,
|
|
||||||
resource_size_t add_size,
|
resource_size_t add_size,
|
||||||
struct list_head *realloc_head)
|
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 min_align, win_align, align, size, size0, size1 = 0;
|
||||||
resource_size_t aligns[28]; /* Alignments from 1MB to 128TB */
|
resource_size_t aligns[28]; /* Alignments from 1MB to 128TB */
|
||||||
int order, max_order;
|
int order, max_order;
|
||||||
struct resource *b_res = find_bus_resource_of_type(bus,
|
struct resource *b_res = pbus_select_window_for_type(bus, type);
|
||||||
mask | IORESOURCE_PREFETCH, type);
|
|
||||||
resource_size_t children_add_size = 0;
|
resource_size_t children_add_size = 0;
|
||||||
resource_size_t children_add_align = 0;
|
resource_size_t children_add_align = 0;
|
||||||
resource_size_t add_align = 0;
|
resource_size_t add_align = 0;
|
||||||
resource_size_t relaxed_align;
|
resource_size_t relaxed_align;
|
||||||
|
|
||||||
if (!b_res)
|
if (!b_res)
|
||||||
return -ENOSPC;
|
return;
|
||||||
|
|
||||||
/* If resource is already assigned, nothing more to do */
|
/* If resource is already assigned, nothing more to do */
|
||||||
if (b_res->parent)
|
if (b_res->parent)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
memset(aligns, 0, sizeof(aligns));
|
memset(aligns, 0, sizeof(aligns));
|
||||||
max_order = 0;
|
max_order = 0;
|
||||||
|
|
@ -1338,11 +1335,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
||||||
if (!pdev_resources_assignable(dev) ||
|
if (!pdev_resources_assignable(dev) ||
|
||||||
!pdev_resource_should_fit(dev, r))
|
!pdev_resource_should_fit(dev, r))
|
||||||
continue;
|
continue;
|
||||||
|
if (b_res != pbus_select_window(bus, r))
|
||||||
if ((r->flags & mask) != type &&
|
|
||||||
(r->flags & mask) != type2 &&
|
|
||||||
(r->flags & mask) != type3)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r_size = resource_size(r);
|
r_size = resource_size(r);
|
||||||
|
|
||||||
/* Put SRIOV requested res to the optional list */
|
/* 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",
|
pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
|
||||||
b_res, &bus->busn_res);
|
b_res, &bus->busn_res);
|
||||||
b_res->flags |= IORESOURCE_DISABLED;
|
b_res->flags |= IORESOURCE_DISABLED;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resource_set_range(b_res, min_align, size0);
|
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) (size1 - size0),
|
||||||
(unsigned long long) add_align);
|
(unsigned long long) add_align);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long pci_cardbus_resource_alignment(struct resource *res)
|
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)
|
void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
unsigned long mask, prefmask, type2 = 0, type3 = 0;
|
|
||||||
resource_size_t additional_io_size = 0, additional_mmio_size = 0,
|
resource_size_t additional_io_size = 0, additional_mmio_size = 0,
|
||||||
additional_mmio_pref_size = 0;
|
additional_mmio_pref_size = 0;
|
||||||
struct resource *pref;
|
struct resource *pref;
|
||||||
struct pci_host_bridge *host;
|
struct pci_host_bridge *host;
|
||||||
int hdr_type, ret;
|
int hdr_type;
|
||||||
|
|
||||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||||
struct pci_bus *b = dev->subordinate;
|
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,
|
pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
|
||||||
additional_io_size, realloc_head);
|
additional_io_size, realloc_head);
|
||||||
|
|
||||||
/*
|
if (pref) {
|
||||||
* If there's a 64-bit prefetchable MMIO window, compute
|
pbus_size_mem(bus,
|
||||||
* the size required to put all 64-bit prefetchable
|
IORESOURCE_MEM | IORESOURCE_PREFETCH |
|
||||||
* resources in it.
|
(pref->flags & IORESOURCE_MEM_64),
|
||||||
*/
|
|
||||||
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,
|
realloc_head ? 0 : additional_mmio_pref_size,
|
||||||
additional_mmio_pref_size, realloc_head);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pbus_size_mem(bus, IORESOURCE_MEM,
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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,
|
|
||||||
realloc_head ? 0 : additional_mmio_size,
|
realloc_head ? 0 : additional_mmio_size,
|
||||||
additional_mmio_size, realloc_head);
|
additional_mmio_size, realloc_head);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue