summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAlison Schofield <alison.schofield@intel.com>2023-11-13 14:13:24 -0800
committerDan Williams <dan.j.williams@intel.com>2023-12-04 17:19:03 -0800
commit659aa050a53817157b7459529538598a6449c1d3 (patch)
tree46f51a30dabf7415363a43fa47e4643262b66ec7 /kernel
parente05501e8a84eee4f819f31b9ce663bddd01b3b69 (diff)
downloadlinux-stable-659aa050a53817157b7459529538598a6449c1d3.tar.gz
linux-stable-659aa050a53817157b7459529538598a6449c1d3.tar.bz2
linux-stable-659aa050a53817157b7459529538598a6449c1d3.zip
kernel/resource: Increment by align value in get_free_mem_region()
Currently get_free_mem_region() searches for available capacity in increments equal to the region size being requested. This can cause the search to take giant steps through the resource leaving needless gaps and missing available space. Specifically 'cxl create-region' fails with ERANGE even though capacity of the given size and CXL's expected 256M x InterleaveWays alignment can be satisfied. Replace the total-request-size increment with a next alignment increment so that the next possible address is always examined for availability. Fixes: 14b80582c43e ("resource: Introduce alloc_free_mem_region()") Reported-by: Dmytro Adamenko <dmytro.adamenko@intel.com> Reported-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/20231113221324.1118092-1-alison.schofield@intel.com Cc: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/resource.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index 866ef3663a0b..91be1bc50b60 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1844,8 +1844,8 @@ get_free_mem_region(struct device *dev, struct resource *base,
write_lock(&resource_lock);
for (addr = gfr_start(base, size, align, flags);
- gfr_continue(base, addr, size, flags);
- addr = gfr_next(addr, size, flags)) {
+ gfr_continue(base, addr, align, flags);
+ addr = gfr_next(addr, align, flags)) {
if (__region_intersects(base, addr, size, 0, IORES_DESC_NONE) !=
REGION_DISJOINT)
continue;