From: Ilpo Järvinen Date: Tue, 24 Mar 2026 16:56:25 +0000 (+0200) Subject: resource: Pass full extent of empty space to resource_alignf callback X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f699bcc8bcdf99565928a7b1fc7ee656f6c81815;p=thirdparty%2Fkernel%2Fstable.git resource: Pass full extent of empty space to resource_alignf callback __find_resource_space() calculates the full extent of empty space but only passes the aligned space to resource_alignf callback. In some situations, the callback may choose take advantage of the free space before the requested alignment. Pass the full extent of the calculated empty space to resource_alignf callback as an additional parameter. Signed-off-by: Ilpo Järvinen Signed-off-by: Bjorn Helgaas Tested-by: Xifer Link: https://patch.msgid.link/20260324165633.4583-3-ilpo.jarvinen@linux.intel.com --- diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 51a8a4c4572ac..11df411b1d182 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -125,6 +125,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); resource_size_t pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index b5793e8fbdc11..5b9b4fcd0e54e 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -560,7 +560,9 @@ char * __init pcibios_setup(char *str) * which might be mirrored at 0x0100-0x03ff.. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, + resource_size_t align) { struct pci_dev *dev = data; resource_size_t start = res->start; diff --git a/arch/m68k/kernel/pcibios.c b/arch/m68k/kernel/pcibios.c index e6ab3f9ff5d88..1415f6e4e5cec 100644 --- a/arch/m68k/kernel/pcibios.c +++ b/arch/m68k/kernel/pcibios.c @@ -27,7 +27,9 @@ * which might be mirrored at 0x0100-0x03ff.. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, + resource_size_t align) { resource_size_t start = res->start; diff --git a/arch/mips/pci/pci-generic.c b/arch/mips/pci/pci-generic.c index d2d68bac3d250..f4957c26efc7e 100644 --- a/arch/mips/pci/pci-generic.c +++ b/arch/mips/pci/pci-generic.c @@ -22,7 +22,8 @@ * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; resource_size_t start = res->start; diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index d04b7c1294b6e..817e97402afe9 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -52,6 +52,7 @@ unsigned long pci_address_to_pio(phys_addr_t address) */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index cf285b17a5aee..f99b20795d5a3 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -196,7 +196,9 @@ void __ref pcibios_init_bridge(struct pci_dev *dev) * than res->start. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t alignment) + const struct resource *empty_res, + resource_size_t size, + resource_size_t alignment) { resource_size_t mask, align, start = res->start; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index a7a2fb6059719..e7bfa15da0435 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1132,7 +1132,9 @@ static int skip_isa_ioresource_align(struct pci_dev *dev) * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, + resource_size_t align) { struct pci_dev *dev = data; resource_size_t start = res->start; diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 2a430722cbe41..39bd2adfc240f 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -266,6 +266,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) } resource_size_t pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align) { diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index a3903304f33fa..7a0522316ee3b 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -168,7 +168,9 @@ subsys_initcall(pcibios_init); * modulo 0x400. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, + resource_size_t align) { struct pci_dev *dev = data; struct pci_channel *hose = dev->sysdata; diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index c4ec39ad276b1..6fbd4b34c3f7d 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -153,7 +153,8 @@ skip_isa_ioresource_align(struct pci_dev *dev) { */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; resource_size_t start = res->start; diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 62c900e400d6a..64ccb7e0d92fb 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -39,6 +39,7 @@ */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index bb2aef373d6fc..c375e255c509b 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -251,10 +251,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, */ resource_size_t __weak pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align) { - return res->start; + return res->start; } static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 0679dd434719d..949e69921fe91 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -602,7 +602,8 @@ static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data, static resource_size_t pcmcia_align(void *align_data, const struct resource *res, - resource_size_t size, resource_size_t align) + const struct resource *empty_res, + resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; struct resource_map *m; diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 19d5e04564d94..3c73c9c0d4f7f 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -202,6 +202,7 @@ enum { * typedef resource_alignf - Resource alignment callback * @data: Private data used by the callback * @res: Resource candidate range (an empty resource space) + * @empty_res: Empty resource range without alignment applied * @size: The minimum size of the empty space * @align: Alignment from the constraints * @@ -212,6 +213,7 @@ enum { */ typedef resource_size_t (*resource_alignf)(void *data, const struct resource *res, + const struct resource *empty_res, resource_size_t size, resource_size_t align); diff --git a/include/linux/pci.h b/include/linux/pci.h index 1c270f1d51230..ac332ff9da9f5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1206,9 +1206,10 @@ int __must_check pcibios_enable_device(struct pci_dev *, int mask); char *pcibios_setup(char *str); /* Used only when drivers/pci/setup.c is used */ -resource_size_t pcibios_align_resource(void *, const struct resource *, - resource_size_t, - resource_size_t); +resource_size_t pcibios_align_resource(void *data, const struct resource *res, + const struct resource *empty_res, + resource_size_t size, + resource_size_t align); /* Generic PCI functions used internally */ diff --git a/kernel/resource.c b/kernel/resource.c index 1e2f1dfc0edda..1b8d3101bdc6a 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -759,7 +759,8 @@ static int __find_resource_space(struct resource *root, struct resource *old, alloc.flags = avail.flags; if (alignf) { alloc.start = alignf(constraint->alignf_data, - &avail, size, constraint->align); + &avail, &tmp, + size, constraint->align); } else { alloc.start = avail.start; }