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

mm/cma: report base address of single range correctly

The cma_declare_contiguous_nid code was refactored by commit c009da4258f9
("mm, cma: support multiple contiguous ranges, if requested"), so that it
could use an internal function to attempt a single range area first, and
then try a multi-range one.

However, that meant that the actual base address used for the !fixed case
(base == 0) wasn't available one level up to be printed in the
informational message, and it would always end up printing a base address
of 0 in the boot message.

Make the internal function take a phys_addr_t pointer to the base address,
so that the value is available to the caller.

[fvdl@google.com: v2]
Link: https://lkml.kernel.org/r/20250408164000.3215690-1-fvdl@google.com
Link: https://lkml.kernel.org/r/20250407165435.2567898-1-fvdl@google.com
Fixes: c009da4258f9 ("mm, cma: support multiple contiguous ranges, if requested")
Signed-off-by: Frank van der Linden <fvdl@google.com>
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Closes: https://lore.kernel.org/linux-mm/CAMuHMdVWviQ7O9yBFE3f=ev0eVb1CnsQvR6SKtEROBbM6z7g3w@mail.gmail.com/
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Frank van der Linden and committed by
Andrew Morton
60580e0b 90abee6d

+11 -8
+11 -8
mm/cma.c
··· 35 35 struct cma cma_areas[MAX_CMA_AREAS]; 36 36 unsigned int cma_area_count; 37 37 38 - static int __init __cma_declare_contiguous_nid(phys_addr_t base, 38 + static int __init __cma_declare_contiguous_nid(phys_addr_t *basep, 39 39 phys_addr_t size, phys_addr_t limit, 40 40 phys_addr_t alignment, unsigned int order_per_bit, 41 41 bool fixed, const char *name, struct cma **res_cma, ··· 370 370 phys_addr_t align, unsigned int order_per_bit, 371 371 const char *name, struct cma **res_cma, int nid) 372 372 { 373 - phys_addr_t start, end; 373 + phys_addr_t start = 0, end; 374 374 phys_addr_t size, sizesum, sizeleft; 375 375 struct cma_init_memrange *mrp, *mlp, *failed; 376 376 struct cma_memrange *cmrp; ··· 384 384 /* 385 385 * First, try it the normal way, producing just one range. 386 386 */ 387 - ret = __cma_declare_contiguous_nid(0, total_size, 0, align, 387 + ret = __cma_declare_contiguous_nid(&start, total_size, 0, align, 388 388 order_per_bit, false, name, res_cma, nid); 389 389 if (ret != -ENOMEM) 390 390 goto out; ··· 580 580 { 581 581 int ret; 582 582 583 - ret = __cma_declare_contiguous_nid(base, size, limit, alignment, 583 + ret = __cma_declare_contiguous_nid(&base, size, limit, alignment, 584 584 order_per_bit, fixed, name, res_cma, nid); 585 585 if (ret != 0) 586 586 pr_err("Failed to reserve %ld MiB\n", ··· 592 592 return ret; 593 593 } 594 594 595 - static int __init __cma_declare_contiguous_nid(phys_addr_t base, 595 + static int __init __cma_declare_contiguous_nid(phys_addr_t *basep, 596 596 phys_addr_t size, phys_addr_t limit, 597 597 phys_addr_t alignment, unsigned int order_per_bit, 598 598 bool fixed, const char *name, struct cma **res_cma, 599 599 int nid) 600 600 { 601 601 phys_addr_t memblock_end = memblock_end_of_DRAM(); 602 - phys_addr_t highmem_start; 602 + phys_addr_t highmem_start, base = *basep; 603 603 int ret; 604 604 605 605 /* ··· 722 722 } 723 723 724 724 ret = cma_init_reserved_mem(base, size, order_per_bit, name, res_cma); 725 - if (ret) 725 + if (ret) { 726 726 memblock_phys_free(base, size); 727 + return ret; 728 + } 727 729 728 730 (*res_cma)->nid = nid; 731 + *basep = base; 729 732 730 - return ret; 733 + return 0; 731 734 } 732 735 733 736 static void cma_debug_show_areas(struct cma *cma)