Skip to content

Commit 4292a1e

Browse files
ij-intelbjorn-helgaas
authored andcommitted
PCI: Refactor distributing available memory to use loops
pci_bus_distribute_available_resources() and pci_bridge_distribute_available_resources() retain bridge window resources and related data needed for distributing the available window in independent variables for io, memory, and prefetchable memory windows. The code is essentially the same for all of them and therefore repeated three times with different variable names. Refactor pci_bus_distribute_available_resources() to take an array. This is complicated slightly by the function taking advantage of passing the struct as value, which cannot be done for arrays in C. Therefore, copy the data into a local array in the stack in the first loop. Variable names are (hopefully) improved slightly as well. 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-21-ilpo.jarvinen@linux.intel.com
1 parent ae88d0b commit 4292a1e

2 files changed

Lines changed: 74 additions & 91 deletions

File tree

drivers/pci/setup-bus.c

Lines changed: 72 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,15 +2059,16 @@ static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
20592059
avail->start = min(avail->start + tmp, avail->end + 1);
20602060
}
20612061

2062-
static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
2063-
struct resource *mmio,
2064-
struct resource *mmio_pref)
2062+
static void remove_dev_resources(struct pci_dev *dev,
2063+
struct resource available[PCI_P2P_BRIDGE_RESOURCE_NUM])
20652064
{
2065+
struct resource *mmio_pref = &available[PCI_BUS_BRIDGE_PREF_MEM_WINDOW];
20662066
struct resource *res;
20672067

20682068
pci_dev_for_each_resource(dev, res) {
20692069
if (resource_type(res) == IORESOURCE_IO) {
2070-
remove_dev_resource(io, dev, res);
2070+
remove_dev_resource(&available[PCI_BUS_BRIDGE_IO_WINDOW],
2071+
dev, res);
20712072
} else if (resource_type(res) == IORESOURCE_MEM) {
20722073

20732074
/*
@@ -2081,10 +2082,13 @@ static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
20812082
*/
20822083
if ((res->flags & IORESOURCE_PREFETCH) &&
20832084
((res->flags & IORESOURCE_MEM_64) ==
2084-
(mmio_pref->flags & IORESOURCE_MEM_64)))
2085-
remove_dev_resource(mmio_pref, dev, res);
2086-
else
2087-
remove_dev_resource(mmio, dev, res);
2085+
(mmio_pref->flags & IORESOURCE_MEM_64))) {
2086+
remove_dev_resource(&available[PCI_BUS_BRIDGE_PREF_MEM_WINDOW],
2087+
dev, res);
2088+
} else {
2089+
remove_dev_resource(&available[PCI_BUS_BRIDGE_MEM_WINDOW],
2090+
dev, res);
2091+
}
20882092
}
20892093
}
20902094
}
@@ -2099,45 +2103,39 @@ static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
20992103
* shared with the bridges.
21002104
*/
21012105
static void pci_bus_distribute_available_resources(struct pci_bus *bus,
2102-
struct list_head *add_list,
2103-
struct resource io,
2104-
struct resource mmio,
2105-
struct resource mmio_pref)
2106+
struct list_head *add_list,
2107+
struct resource available_in[PCI_P2P_BRIDGE_RESOURCE_NUM])
21062108
{
2109+
struct resource available[PCI_P2P_BRIDGE_RESOURCE_NUM];
21072110
unsigned int normal_bridges = 0, hotplug_bridges = 0;
2108-
struct resource *io_res, *mmio_res, *mmio_pref_res;
21092111
struct pci_dev *dev, *bridge = bus->self;
2110-
resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align;
2112+
resource_size_t per_bridge[PCI_P2P_BRIDGE_RESOURCE_NUM];
2113+
resource_size_t align;
2114+
int i;
21112115

2112-
io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
2113-
mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
2114-
mmio_pref_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
2116+
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) {
2117+
struct resource *res = pci_bus_resource_n(bus, i);
21152118

2116-
/*
2117-
* The alignment of this bridge is yet to be considered, hence it must
2118-
* be done now before extending its bridge window.
2119-
*/
2120-
align = pci_resource_alignment(bridge, io_res);
2121-
if (!io_res->parent && align)
2122-
io.start = min(ALIGN(io.start, align), io.end + 1);
2123-
2124-
align = pci_resource_alignment(bridge, mmio_res);
2125-
if (!mmio_res->parent && align)
2126-
mmio.start = min(ALIGN(mmio.start, align), mmio.end + 1);
2119+
available[i] = available_in[i];
21272120

2128-
align = pci_resource_alignment(bridge, mmio_pref_res);
2129-
if (!mmio_pref_res->parent && align)
2130-
mmio_pref.start = min(ALIGN(mmio_pref.start, align),
2131-
mmio_pref.end + 1);
2121+
/*
2122+
* The alignment of this bridge is yet to be considered,
2123+
* hence it must be done now before extending its bridge
2124+
* window.
2125+
*/
2126+
align = pci_resource_alignment(bridge, res);
2127+
if (!res->parent && align)
2128+
available[i].start = min(ALIGN(available[i].start, align),
2129+
available[i].end + 1);
21322130

2133-
/*
2134-
* Now that we have adjusted for alignment, update the bridge window
2135-
* resources to fill as much remaining resource space as possible.
2136-
*/
2137-
adjust_bridge_window(bridge, io_res, add_list, resource_size(&io));
2138-
adjust_bridge_window(bridge, mmio_res, add_list, resource_size(&mmio));
2139-
adjust_bridge_window(bridge, mmio_pref_res, add_list,
2140-
resource_size(&mmio_pref));
2131+
/*
2132+
* Now that we have adjusted for alignment, update the
2133+
* bridge window resources to fill as much remaining
2134+
* resource space as possible.
2135+
*/
2136+
adjust_bridge_window(bridge, res, add_list,
2137+
resource_size(&available[i]));
2138+
}
21412139

21422140
/*
21432141
* Calculate how many hotplug bridges and normal bridges there
@@ -2161,7 +2159,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
21612159
*/
21622160
list_for_each_entry(dev, &bus->devices, bus_list) {
21632161
if (!dev->is_virtfn)
2164-
remove_dev_resources(dev, &io, &mmio, &mmio_pref);
2162+
remove_dev_resources(dev, available);
21652163
}
21662164

21672165
/*
@@ -2173,16 +2171,9 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
21732171
* split between non-hotplug bridges. This is to allow possible
21742172
* hotplug bridges below them to get the extra space as well.
21752173
*/
2176-
if (hotplug_bridges) {
2177-
io_per_b = div64_ul(resource_size(&io), hotplug_bridges);
2178-
mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges);
2179-
mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
2180-
hotplug_bridges);
2181-
} else {
2182-
io_per_b = div64_ul(resource_size(&io), normal_bridges);
2183-
mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges);
2184-
mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
2185-
normal_bridges);
2174+
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) {
2175+
per_bridge[i] = div64_ul(resource_size(&available[i]),
2176+
hotplug_bridges ?: normal_bridges);
21862177
}
21872178

21882179
for_each_pci_bridge(dev, bus) {
@@ -2195,64 +2186,55 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
21952186
if (hotplug_bridges && !dev->is_hotplug_bridge)
21962187
continue;
21972188

2198-
res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
2189+
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) {
2190+
res = pci_bus_resource_n(bus, i);
21992191

2200-
/*
2201-
* Make sure the split resource space is properly aligned
2202-
* for bridge windows (align it down to avoid going above
2203-
* what is available).
2204-
*/
2205-
align = pci_resource_alignment(dev, res);
2206-
resource_set_size(&io, ALIGN_DOWN_IF_NONZERO(io_per_b, align));
2207-
2208-
/*
2209-
* The x_per_b holds the extra resource space that can be
2210-
* added for each bridge but there is the minimal already
2211-
* reserved as well so adjust x.start down accordingly to
2212-
* cover the whole space.
2213-
*/
2214-
io.start -= resource_size(res);
2215-
2216-
res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
2217-
align = pci_resource_alignment(dev, res);
2218-
resource_set_size(&mmio,
2219-
ALIGN_DOWN_IF_NONZERO(mmio_per_b,align));
2220-
mmio.start -= resource_size(res);
2192+
/*
2193+
* Make sure the split resource space is properly
2194+
* aligned for bridge windows (align it down to
2195+
* avoid going above what is available).
2196+
*/
2197+
align = pci_resource_alignment(dev, res);
2198+
resource_set_size(&available[i],
2199+
ALIGN_DOWN_IF_NONZERO(per_bridge[i],
2200+
align));
22212201

2222-
res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
2223-
align = pci_resource_alignment(dev, res);
2224-
resource_set_size(&mmio_pref,
2225-
ALIGN_DOWN_IF_NONZERO(mmio_pref_per_b, align));
2226-
mmio_pref.start -= resource_size(res);
2202+
/*
2203+
* The per_bridge holds the extra resource space
2204+
* that can be added for each bridge but there is
2205+
* the minimal already reserved as well so adjust
2206+
* x.start down accordingly to cover the whole
2207+
* space.
2208+
*/
2209+
available[i].start -= resource_size(res);
2210+
}
22272211

2228-
pci_bus_distribute_available_resources(b, add_list, io, mmio,
2229-
mmio_pref);
2212+
pci_bus_distribute_available_resources(b, add_list, available);
22302213

2231-
io.start += io.end + 1;
2232-
mmio.start += mmio.end + 1;
2233-
mmio_pref.start += mmio_pref.end + 1;
2214+
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++)
2215+
available[i].start += available[i].end + 1;
22342216
}
22352217
}
22362218

22372219
static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
22382220
struct list_head *add_list)
22392221
{
2240-
struct resource available_io, available_mmio, available_mmio_pref;
2222+
struct resource *res, available[PCI_P2P_BRIDGE_RESOURCE_NUM];
2223+
unsigned int i;
22412224

22422225
if (!bridge->is_hotplug_bridge)
22432226
return;
22442227

22452228
pci_dbg(bridge, "distributing available resources\n");
22462229

22472230
/* Take the initial extra resources from the hotplug port */
2248-
available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW];
2249-
available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW];
2250-
available_mmio_pref = bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
2231+
for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) {
2232+
res = pci_resource_n(bridge, PCI_BRIDGE_RESOURCES + i);
2233+
available[i] = *res;
2234+
}
22512235

22522236
pci_bus_distribute_available_resources(bridge->subordinate,
2253-
add_list, available_io,
2254-
available_mmio,
2255-
available_mmio_pref);
2237+
add_list, available);
22562238
}
22572239

22582240
static bool pci_bridge_resources_not_assigned(struct pci_dev *dev)

include/linux/pci.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ enum {
119119
#define PCI_CB_BRIDGE_MEM_1_WINDOW (PCI_BRIDGE_RESOURCES + 3)
120120

121121
/* Total number of bridge resources for P2P and CardBus */
122-
#define PCI_BRIDGE_RESOURCE_NUM 4
122+
#define PCI_P2P_BRIDGE_RESOURCE_NUM 3
123+
#define PCI_BRIDGE_RESOURCE_NUM 4
123124

124125
/* Resources assigned to buses behind the bridge */
125126
PCI_BRIDGE_RESOURCES,

0 commit comments

Comments
 (0)