Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: Stop over-estimating bridge window size

New way to calculate the bridge window head alignment produces tight-fit,
that is, it does not leave any gaps between the resources. Similarly,
relaxed tail alignment does not leave extra tail room.

Start to use bridge window calculation that does not over-estimate the size
of the required window.

pbus_upstream_space_available() can be removed.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Malte Schröder <malte+lkml@tnxip.de>
Link: https://patch.msgid.link/20251219174036.16738-4-ilpo.jarvinen@linux.intel.com

authored by

Ilpo Järvinen and committed by
Bjorn Helgaas
3958bf16 bc75c8e5

+5 -92
+5 -92
drivers/pci/setup-bus.c
··· 1268 1268 } 1269 1269 1270 1270 /** 1271 - * pbus_upstream_space_available - Check no upstream resource limits allocation 1272 - * @bus: The bus 1273 - * @res: The resource to help select the correct bridge window 1274 - * @size: The size required from the bridge window 1275 - * @align: Required alignment for the resource 1276 - * 1277 - * Check that @size can fit inside the upstream bridge resources that are 1278 - * already assigned. Select the upstream bridge window based on the type of 1279 - * @res. 1280 - * 1281 - * Return: %true if enough space is available on all assigned upstream 1282 - * resources. 1283 - */ 1284 - static bool pbus_upstream_space_available(struct pci_bus *bus, 1285 - struct resource *res, 1286 - resource_size_t size, 1287 - resource_size_t align) 1288 - { 1289 - struct resource_constraint constraint = { 1290 - .max = RESOURCE_SIZE_MAX, 1291 - .align = align, 1292 - }; 1293 - struct pci_bus *downstream = bus; 1294 - 1295 - while ((bus = bus->parent)) { 1296 - if (pci_is_root_bus(bus)) 1297 - break; 1298 - 1299 - res = pbus_select_window(bus, res); 1300 - if (!res) 1301 - return false; 1302 - if (!res->parent) 1303 - continue; 1304 - 1305 - if (resource_size(res) >= size) { 1306 - struct resource gap = {}; 1307 - 1308 - if (find_resource_space(res, &gap, size, &constraint) == 0) { 1309 - gap.flags = res->flags; 1310 - pci_dbg(bus->self, 1311 - "Assigned bridge window %pR to %pR free space at %pR\n", 1312 - res, &bus->busn_res, &gap); 1313 - return true; 1314 - } 1315 - } 1316 - 1317 - if (bus->self) { 1318 - pci_info(bus->self, 1319 - "Assigned bridge window %pR to %pR cannot fit 0x%llx required for %s bridging to %pR\n", 1320 - res, &bus->busn_res, 1321 - (unsigned long long)size, 1322 - pci_name(downstream->self), 1323 - &downstream->busn_res); 1324 - } 1325 - 1326 - return false; 1327 - } 1328 - 1329 - return true; 1330 - } 1331 - 1332 - /** 1333 1271 * pbus_size_mem() - Size the memory window of a given bus 1334 1272 * 1335 1273 * @bus: The bus ··· 1293 1355 struct pci_dev *dev; 1294 1356 resource_size_t min_align, win_align, align, size, size0, size1 = 0; 1295 1357 resource_size_t aligns[28] = {}; /* Alignments from 1MB to 128TB */ 1296 - resource_size_t aligns2[28] = {};/* Alignments from 1MB to 128TB */ 1297 1358 int order, max_order; 1298 1359 struct resource *b_res = pbus_select_window_for_type(bus, type); 1299 1360 resource_size_t children_add_size = 0; ··· 1351 1414 continue; 1352 1415 } 1353 1416 size += max(r_size, align); 1354 - /* 1355 - * Exclude ranges with size > align from calculation of 1356 - * the alignment. 1357 - */ 1358 - if (r_size <= align) 1359 - aligns[order] += align; 1360 - aligns2[order] += align; 1417 + 1418 + aligns[order] += align; 1361 1419 if (order > max_order) 1362 1420 max_order = order; 1363 1421 ··· 1366 1434 1367 1435 old_size = resource_size(b_res); 1368 1436 win_align = window_alignment(bus, b_res->flags); 1369 - min_align = calculate_mem_align(aligns, max_order); 1437 + min_align = calculate_head_align(aligns, max_order); 1370 1438 min_align = max(min_align, win_align); 1371 - size0 = calculate_memsize(size, min_size, 0, 0, old_size, min_align); 1439 + size0 = calculate_memsize(size, min_size, 0, 0, old_size, win_align); 1372 1440 1373 1441 if (size0) { 1374 1442 resource_set_range(b_res, min_align, size0); 1375 1443 b_res->flags &= ~IORESOURCE_DISABLED; 1376 1444 } 1377 1445 1378 - if (bus->self && size0 && 1379 - !pbus_upstream_space_available(bus, b_res, size0, min_align)) { 1380 - min_align = calculate_head_align(aligns2, max_order); 1381 - size0 = calculate_memsize(size, min_size, 0, 0, old_size, win_align); 1382 - resource_set_range(b_res, min_align, size0); 1383 - pci_info(bus->self, "bridge window %pR to %pR requires relaxed alignment rules\n", 1384 - b_res, &bus->busn_res); 1385 - } 1386 - 1387 1446 if (realloc_head && (add_size > 0 || children_add_size > 0)) { 1388 1447 add_align = max(min_align, add_align); 1389 1448 size1 = calculate_memsize(size, min_size, add_size, children_add_size, 1390 - old_size, add_align); 1391 - 1392 - if (bus->self && size1 && 1393 - !pbus_upstream_space_available(bus, b_res, size1, add_align)) { 1394 - min_align = calculate_head_align(aligns2, max_order); 1395 - size1 = calculate_memsize(size, min_size, add_size, children_add_size, 1396 - old_size, win_align); 1397 - pci_info(bus->self, 1398 - "bridge window %pR to %pR requires relaxed alignment rules\n", 1399 - b_res, &bus->busn_res); 1400 - } 1449 + old_size, win_align); 1401 1450 } 1402 1451 1403 1452 if (!size0 && !size1) {