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

memblock: make memblock_find_in_range method private

There are a lot of uses of memblock_find_in_range() along with
memblock_reserve() from the times memblock allocation APIs did not exist.

memblock_find_in_range() is the very core of memblock allocations, so any
future changes to its internal behaviour would mandate updates of all the
users outside memblock.

Replace the calls to memblock_find_in_range() with an equivalent calls to
memblock_phys_alloc() and memblock_phys_alloc_range() and make
memblock_find_in_range() private method of memblock.

This simplifies the callers, ensures that (unlikely) errors in
memblock_reserve() are handled and improves maintainability of
memblock_find_in_range().

Link: https://lkml.kernel.org/r/20210816122622.30279-1-rppt@kernel.org
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> [arm64]
Acked-by: Kirill A. Shutemov <kirill.shtuemov@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> [ACPI]
Acked-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Acked-by: Nick Kossifidis <mick@ics.forth.gr> [riscv]
Tested-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mike Rapoport and committed by
Linus Torvalds
a7259df7 38b031dd

+82 -118
+7 -13
arch/arm/kernel/setup.c
··· 1012 1012 unsigned long long lowmem_max = __pa(high_memory - 1) + 1; 1013 1013 if (crash_max > lowmem_max) 1014 1014 crash_max = lowmem_max; 1015 - crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max, 1016 - crash_size, CRASH_ALIGN); 1015 + 1016 + crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, 1017 + CRASH_ALIGN, crash_max); 1017 1018 if (!crash_base) { 1018 1019 pr_err("crashkernel reservation failed - No suitable area found.\n"); 1019 1020 return; 1020 1021 } 1021 1022 } else { 1023 + unsigned long long crash_max = crash_base + crash_size; 1022 1024 unsigned long long start; 1023 1025 1024 - start = memblock_find_in_range(crash_base, 1025 - crash_base + crash_size, 1026 - crash_size, SECTION_SIZE); 1027 - if (start != crash_base) { 1026 + start = memblock_phys_alloc_range(crash_size, SECTION_SIZE, 1027 + crash_base, crash_max); 1028 + if (!start) { 1028 1029 pr_err("crashkernel reservation failed - memory is in use.\n"); 1029 1030 return; 1030 1031 } 1031 - } 1032 - 1033 - ret = memblock_reserve(crash_base, crash_size); 1034 - if (ret < 0) { 1035 - pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n", 1036 - (unsigned long)crash_base); 1037 - return; 1038 1032 } 1039 1033 1040 1034 pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
+3 -6
arch/arm64/kvm/hyp/reserved_mem.c
··· 92 92 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE. 93 93 */ 94 94 hyp_mem_size = hyp_mem_pages << PAGE_SHIFT; 95 - hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(), 96 - ALIGN(hyp_mem_size, PMD_SIZE), 97 - PMD_SIZE); 95 + hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE), 96 + PMD_SIZE); 98 97 if (!hyp_mem_base) 99 - hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(), 100 - hyp_mem_size, PAGE_SIZE); 98 + hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE); 101 99 else 102 100 hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE); 103 101 ··· 103 105 kvm_err("Failed to reserve hyp memory\n"); 104 106 return; 105 107 } 106 - memblock_reserve(hyp_mem_base, hyp_mem_size); 107 108 108 109 kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20, 109 110 hyp_mem_base);
+11 -25
arch/arm64/mm/init.c
··· 74 74 static void __init reserve_crashkernel(void) 75 75 { 76 76 unsigned long long crash_base, crash_size; 77 + unsigned long long crash_max = arm64_dma_phys_limit; 77 78 int ret; 78 79 79 80 ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(), ··· 85 84 86 85 crash_size = PAGE_ALIGN(crash_size); 87 86 88 - if (crash_base == 0) { 89 - /* Current arm64 boot protocol requires 2MB alignment */ 90 - crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, 91 - crash_size, SZ_2M); 92 - if (crash_base == 0) { 93 - pr_warn("cannot allocate crashkernel (size:0x%llx)\n", 94 - crash_size); 95 - return; 96 - } 97 - } else { 98 - /* User specifies base address explicitly. */ 99 - if (!memblock_is_region_memory(crash_base, crash_size)) { 100 - pr_warn("cannot reserve crashkernel: region is not memory\n"); 101 - return; 102 - } 87 + /* User specifies base address explicitly. */ 88 + if (crash_base) 89 + crash_max = crash_base + crash_size; 103 90 104 - if (memblock_is_region_reserved(crash_base, crash_size)) { 105 - pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n"); 106 - return; 107 - } 108 - 109 - if (!IS_ALIGNED(crash_base, SZ_2M)) { 110 - pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n"); 111 - return; 112 - } 91 + /* Current arm64 boot protocol requires 2MB alignment */ 92 + crash_base = memblock_phys_alloc_range(crash_size, SZ_2M, 93 + crash_base, crash_max); 94 + if (!crash_base) { 95 + pr_warn("cannot allocate crashkernel (size:0x%llx)\n", 96 + crash_size); 97 + return; 113 98 } 114 - memblock_reserve(crash_base, crash_size); 115 99 116 100 pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n", 117 101 crash_base, crash_base + crash_size, crash_size >> 20);
+6 -8
arch/mips/kernel/setup.c
··· 452 452 return; 453 453 454 454 if (crash_base <= 0) { 455 - crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX, 456 - crash_size, CRASH_ALIGN); 455 + crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, 456 + CRASH_ALIGN, 457 + CRASH_ADDR_MAX); 457 458 if (!crash_base) { 458 459 pr_warn("crashkernel reservation failed - No suitable area found.\n"); 459 460 return; ··· 462 461 } else { 463 462 unsigned long long start; 464 463 465 - start = memblock_find_in_range(crash_base, crash_base + crash_size, 466 - crash_size, 1); 464 + start = memblock_phys_alloc_range(crash_size, 1, 465 + crash_base, 466 + crash_base + crash_size); 467 467 if (start != crash_base) { 468 468 pr_warn("Invalid memory region reserved for crash kernel\n"); 469 469 return; ··· 658 656 mips_reserve_vmcore(); 659 657 660 658 mips_parse_crashkernel(); 661 - #ifdef CONFIG_KEXEC 662 - if (crashk_res.start != crashk_res.end) 663 - memblock_reserve(crashk_res.start, resource_size(&crashk_res)); 664 - #endif 665 659 device_tree_init(); 666 660 667 661 /*
+15 -31
arch/riscv/mm/init.c
··· 819 819 820 820 crash_size = PAGE_ALIGN(crash_size); 821 821 822 - if (crash_base == 0) { 823 - /* 824 - * Current riscv boot protocol requires 2MB alignment for 825 - * RV64 and 4MB alignment for RV32 (hugepage size) 826 - */ 827 - crash_base = memblock_find_in_range(search_start, search_end, 828 - crash_size, PMD_SIZE); 829 - 830 - if (crash_base == 0) { 831 - pr_warn("crashkernel: couldn't allocate %lldKB\n", 832 - crash_size >> 10); 833 - return; 834 - } 835 - } else { 836 - /* User specifies base address explicitly. */ 837 - if (!memblock_is_region_memory(crash_base, crash_size)) { 838 - pr_warn("crashkernel: requested region is not memory\n"); 839 - return; 840 - } 841 - 842 - if (memblock_is_region_reserved(crash_base, crash_size)) { 843 - pr_warn("crashkernel: requested region is reserved\n"); 844 - return; 845 - } 846 - 847 - 848 - if (!IS_ALIGNED(crash_base, PMD_SIZE)) { 849 - pr_warn("crashkernel: requested region is misaligned\n"); 850 - return; 851 - } 822 + if (crash_base) { 823 + search_start = crash_base; 824 + search_end = crash_base + crash_size; 852 825 } 853 - memblock_reserve(crash_base, crash_size); 826 + 827 + /* 828 + * Current riscv boot protocol requires 2MB alignment for 829 + * RV64 and 4MB alignment for RV32 (hugepage size) 830 + */ 831 + crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, 832 + search_start, search_end); 833 + if (crash_base == 0) { 834 + pr_warn("crashkernel: couldn't allocate %lldKB\n", 835 + crash_size >> 10); 836 + return; 837 + } 854 838 855 839 pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n", 856 840 crash_base, crash_base + crash_size, crash_size >> 20);
+6 -3
arch/s390/kernel/setup.c
··· 626 626 return; 627 627 } 628 628 low = crash_base ?: low; 629 - crash_base = memblock_find_in_range(low, high, crash_size, 630 - KEXEC_CRASH_MEM_ALIGN); 629 + crash_base = memblock_phys_alloc_range(crash_size, 630 + KEXEC_CRASH_MEM_ALIGN, 631 + low, high); 631 632 } 632 633 633 634 if (!crash_base) { ··· 637 636 return; 638 637 } 639 638 640 - if (register_memory_notifier(&kdump_mem_nb)) 639 + if (register_memory_notifier(&kdump_mem_nb)) { 640 + memblock_free(crash_base, crash_size); 641 641 return; 642 + } 642 643 643 644 if (!OLDMEM_BASE && MACHINE_IS_VM) 644 645 diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
+2 -3
arch/x86/kernel/aperture_64.c
··· 109 109 * memory. Unfortunately we cannot move it up because that would 110 110 * make the IOMMU useless. 111 111 */ 112 - addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR, 113 - aper_size, aper_size); 112 + addr = memblock_phys_alloc_range(aper_size, aper_size, 113 + GART_MIN_ADDR, GART_MAX_ADDR); 114 114 if (!addr) { 115 115 pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n", 116 116 addr, addr + aper_size - 1, aper_size >> 10); 117 117 return 0; 118 118 } 119 - memblock_reserve(addr, aper_size); 120 119 pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n", 121 120 addr, addr + aper_size - 1, aper_size >> 10); 122 121 register_nosave_region(addr >> PAGE_SHIFT,
+15 -8
arch/x86/mm/init.c
··· 127 127 unsigned long ret = 0; 128 128 129 129 if (min_pfn_mapped < max_pfn_mapped) { 130 - ret = memblock_find_in_range( 130 + ret = memblock_phys_alloc_range( 131 + PAGE_SIZE * num, PAGE_SIZE, 131 132 min_pfn_mapped << PAGE_SHIFT, 132 - max_pfn_mapped << PAGE_SHIFT, 133 - PAGE_SIZE * num , PAGE_SIZE); 133 + max_pfn_mapped << PAGE_SHIFT); 134 134 } 135 - if (ret) 136 - memblock_reserve(ret, PAGE_SIZE * num); 137 - else if (can_use_brk_pgt) 135 + if (!ret && can_use_brk_pgt) 138 136 ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE)); 139 137 140 138 if (!ret) ··· 608 610 unsigned long addr; 609 611 unsigned long mapped_ram_size = 0; 610 612 611 - /* xen has big range in reserved near end of ram, skip it at first.*/ 612 - addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE); 613 + /* 614 + * Systems that have many reserved areas near top of the memory, 615 + * e.g. QEMU with less than 1G RAM and EFI enabled, or Xen, will 616 + * require lots of 4K mappings which may exhaust pgt_buf. 617 + * Start with top-most PMD_SIZE range aligned at PMD_SIZE to ensure 618 + * there is enough mapped memory that can be allocated from 619 + * memblock. 620 + */ 621 + addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE, map_start, 622 + map_end); 623 + memblock_free(addr, PMD_SIZE); 613 624 real_end = addr + PMD_SIZE; 614 625 615 626 /* step_size need to be small so pgt_buf from BRK could cover it */
+2 -3
arch/x86/mm/numa.c
··· 376 376 cnt++; 377 377 size = cnt * cnt * sizeof(numa_distance[0]); 378 378 379 - phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped), 380 - size, PAGE_SIZE); 379 + phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 380 + PFN_PHYS(max_pfn_mapped)); 381 381 if (!phys) { 382 382 pr_warn("Warning: can't allocate distance table!\n"); 383 383 /* don't retry until explicitly reset */ 384 384 numa_distance = (void *)1LU; 385 385 return -ENOMEM; 386 386 } 387 - memblock_reserve(phys, size); 388 387 389 388 numa_distance = __va(phys); 390 389 numa_distance_cnt = cnt;
+2 -3
arch/x86/mm/numa_emulation.c
··· 447 447 if (numa_dist_cnt) { 448 448 u64 phys; 449 449 450 - phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped), 451 - phys_size, PAGE_SIZE); 450 + phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0, 451 + PFN_PHYS(max_pfn_mapped)); 452 452 if (!phys) { 453 453 pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n"); 454 454 goto no_emu; 455 455 } 456 - memblock_reserve(phys, phys_size); 457 456 phys_dist = __va(phys); 458 457 459 458 for (i = 0; i < numa_dist_cnt; i++)
+1 -1
arch/x86/realmode/init.c
··· 28 28 WARN_ON(slab_is_available()); 29 29 30 30 /* Has to be under 1M so we can execute real-mode AP code. */ 31 - mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); 31 + mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20); 32 32 if (!mem) 33 33 pr_info("No sub-1M memory is available for the trampoline\n"); 34 34 else
+2 -3
drivers/acpi/tables.c
··· 583 583 } 584 584 585 585 acpi_tables_addr = 586 - memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS, 587 - all_tables_size, PAGE_SIZE); 586 + memblock_phys_alloc_range(all_tables_size, PAGE_SIZE, 587 + 0, ACPI_TABLE_UPGRADE_MAX_PHYS); 588 588 if (!acpi_tables_addr) { 589 589 WARN_ON(1); 590 590 return; ··· 599 599 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area) 600 600 * works fine. 601 601 */ 602 - memblock_reserve(acpi_tables_addr, all_tables_size); 603 602 arch_reserve_mem_area(acpi_tables_addr, all_tables_size); 604 603 605 604 /*
+1 -4
drivers/base/arch_numa.c
··· 279 279 int i, j; 280 280 281 281 size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]); 282 - phys = memblock_find_in_range(0, PFN_PHYS(max_pfn), 283 - size, PAGE_SIZE); 282 + phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn)); 284 283 if (WARN_ON(!phys)) 285 284 return -ENOMEM; 286 - 287 - memblock_reserve(phys, size); 288 285 289 286 numa_distance = __va(phys); 290 287 numa_distance_cnt = nr_node_ids;
+8 -4
drivers/of/of_reserved_mem.c
··· 33 33 phys_addr_t *res_base) 34 34 { 35 35 phys_addr_t base; 36 + int err = 0; 36 37 37 38 end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; 38 39 align = !align ? SMP_CACHE_BYTES : align; 39 - base = memblock_find_in_range(start, end, size, align); 40 + base = memblock_phys_alloc_range(size, align, start, end); 40 41 if (!base) 41 42 return -ENOMEM; 42 43 43 44 *res_base = base; 44 - if (nomap) 45 - return memblock_mark_nomap(base, size); 45 + if (nomap) { 46 + err = memblock_mark_nomap(base, size); 47 + if (err) 48 + memblock_free(base, size); 49 + } 46 50 47 - return memblock_reserve(base, size); 51 + return err; 48 52 } 49 53 50 54 /*
-2
include/linux/memblock.h
··· 99 99 static inline void memblock_discard(void) {} 100 100 #endif 101 101 102 - phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, 103 - phys_addr_t size, phys_addr_t align); 104 102 void memblock_allow_resize(void); 105 103 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid); 106 104 int memblock_add(phys_addr_t base, phys_addr_t size);
+1 -1
mm/memblock.c
··· 315 315 * Return: 316 316 * Found address on success, 0 on failure. 317 317 */ 318 - phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start, 318 + static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start, 319 319 phys_addr_t end, phys_addr_t size, 320 320 phys_addr_t align) 321 321 {