diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 03636d799837..3e99a697fce7 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6611,6 +6611,9 @@ Kernel parameters reserve_mem=12M:4096:oops ramoops.mem_name=oops + Both the size and the alignment must be multiples of + the page size. + reservetop= [X86-32,EARLY] Format: nn[KMG] Reserves a hole at the top of the kernel virtual diff --git a/include/linux/memblock.h b/include/linux/memblock.h index d62db9e776cf..01a2dea5aa11 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -162,7 +162,6 @@ int memblock_mark_kho_scratch(phys_addr_t base, phys_addr_t size); int memblock_clear_kho_scratch(phys_addr_t base, phys_addr_t size); void memblock_free(void *ptr, size_t size); -void reset_all_zones_managed_pages(void); /* Low level functions */ void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags, @@ -413,9 +412,6 @@ static __always_inline phys_addr_t memblock_phys_alloc(phys_addr_t size, MEMBLOCK_ALLOC_ACCESSIBLE); } -void *memblock_alloc_exact_nid_raw(phys_addr_t size, phys_addr_t align, - phys_addr_t min_addr, phys_addr_t max_addr, - int nid); void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid); diff --git a/mm/memblock.c b/mm/memblock.c index e6fdf95a0534..fa2754ccd491 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -155,11 +155,6 @@ struct memblock_type physmem = { */ static __refdata struct memblock_type *memblock_memory = &memblock.memory; -#define for_each_memblock_type(i, memblock_type, rgn) \ - for (i = 0, rgn = &memblock_type->regions[0]; \ - i < memblock_type->cnt; \ - i++, rgn = &memblock_type->regions[i]) - #define memblock_dbg(fmt, ...) \ do { \ if (memblock_debug) \ @@ -591,6 +586,29 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type, type->total_size += size; } +/** + * __memblock_search - Find the first region index where rend > base + * @type: memblock type to search + * @base: base physical address of the candidate range + * + * Return: the first region index that could potentially overlap @base. + */ +static int __init_memblock __memblock_search(struct memblock_type *type, + phys_addr_t base) +{ + int mid, low = 0; + int high = type->cnt; + + while (low < high) { + mid = (low + high) / 2; + if (type->regions[mid].base + type->regions[mid].size <= base) + low = mid + 1; + else + high = mid; + } + return low; +} + /** * memblock_add_range - add new memblock region * @type: memblock type to add new region into @@ -614,8 +632,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, bool insert = false; phys_addr_t obase = base; phys_addr_t end = base + memblock_cap_size(base, &size); - int idx, nr_new, start_rgn = -1, end_rgn; - struct memblock_region *rgn; + int idx, nr_new, start_rgn = -1, end_rgn = 0; if (!size) return 0; @@ -651,7 +668,8 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, base = obase; nr_new = 0; - for_each_memblock_type(idx, type, rgn) { + for (idx = __memblock_search(type, base); idx < type->cnt; idx++) { + struct memblock_region *rgn = &type->regions[idx]; phys_addr_t rbase = rgn->base; phys_addr_t rend = rbase + rgn->size; @@ -814,8 +832,6 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, int *start_rgn, int *end_rgn) { phys_addr_t end = base + memblock_cap_size(base, &size); - int idx; - struct memblock_region *rgn; *start_rgn = *end_rgn = 0; @@ -827,7 +843,8 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, if (memblock_double_array(type, base, size) < 0) return -ENOMEM; - for_each_memblock_type(idx, type, rgn) { + for (int idx = __memblock_search(type, base); idx < type->cnt; idx++) { + struct memblock_region *rgn = &type->regions[idx]; phys_addr_t rbase = rgn->base; phys_addr_t rend = rbase + rgn->size; @@ -1659,7 +1676,6 @@ phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t ali * @min_addr: the lower bound of the memory region to allocate (phys address) * @max_addr: the upper bound of the memory region to allocate (phys address) * @nid: nid of the free area to find, %NUMA_NO_NODE for any node - * @exact_nid: control the allocation fall back to other nodes * * Allocates memory block using memblock_alloc_range_nid() and * converts the returned physical address to virtual. @@ -1675,7 +1691,7 @@ phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t ali static void * __init memblock_alloc_internal( phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, - int nid, bool exact_nid) + int nid) { phys_addr_t alloc; @@ -1684,12 +1700,12 @@ static void * __init memblock_alloc_internal( max_addr = memblock.current_limit; alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid, - exact_nid); + false); /* retry allocation without lower limit */ if (!alloc && min_addr) alloc = memblock_alloc_range_nid(size, align, 0, max_addr, nid, - exact_nid); + false); if (!alloc) return NULL; @@ -1697,37 +1713,6 @@ static void * __init memblock_alloc_internal( return phys_to_virt(alloc); } -/** - * memblock_alloc_exact_nid_raw - allocate boot memory block on the exact node - * without zeroing memory - * @size: size of memory block to be allocated in bytes - * @align: alignment of the region and block's size - * @min_addr: the lower bound of the memory region from where the allocation - * is preferred (phys address) - * @max_addr: the upper bound of the memory region from where the allocation - * is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to - * allocate only from memory limited by memblock.current_limit value - * @nid: nid of the free area to find, %NUMA_NO_NODE for any node - * - * Public function, provides additional debug information (including caller - * info), if enabled. Does not zero allocated memory. - * - * Return: - * Virtual address of allocated memory block on success, NULL on failure. - */ -void * __init memblock_alloc_exact_nid_raw( - phys_addr_t size, phys_addr_t align, - phys_addr_t min_addr, phys_addr_t max_addr, - int nid) -{ - memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS\n", - __func__, (u64)size, (u64)align, nid, &min_addr, - &max_addr, (void *)_RET_IP_); - - return memblock_alloc_internal(size, align, min_addr, max_addr, nid, - true); -} - /** * memblock_alloc_try_nid_raw - allocate boot memory block without zeroing * memory and without panicking @@ -1756,8 +1741,7 @@ void * __init memblock_alloc_try_nid_raw( __func__, (u64)size, (u64)align, nid, &min_addr, &max_addr, (void *)_RET_IP_); - return memblock_alloc_internal(size, align, min_addr, max_addr, nid, - false); + return memblock_alloc_internal(size, align, min_addr, max_addr, nid); } /** @@ -1858,8 +1842,7 @@ void * __init memblock_alloc_try_nid( memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS\n", __func__, (u64)size, (u64)align, nid, &min_addr, &max_addr, (void *)_RET_IP_); - ptr = memblock_alloc_internal(size, align, - min_addr, max_addr, nid, false); + ptr = memblock_alloc_internal(size, align, min_addr, max_addr, nid); if (ptr) memset(ptr, 0, size); @@ -2067,19 +2050,10 @@ void __init memblock_mem_limit_remove_map(phys_addr_t limit) static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr) { - unsigned int left = 0, right = type->cnt; + int idx = __memblock_search(type, addr); - do { - unsigned int mid = (right + left) / 2; - - if (addr < type->regions[mid].base) - right = mid; - else if (addr >= (type->regions[mid].base + - type->regions[mid].size)) - left = mid + 1; - else - return mid; - } while (left < right); + if (idx < type->cnt && addr >= type->regions[idx].base) + return idx; return -1; } @@ -2194,11 +2168,11 @@ static void __init_memblock memblock_dump(struct memblock_type *type) phys_addr_t base, end, size; enum memblock_flags flags; int idx; - struct memblock_region *rgn; pr_info(" %s.cnt = 0x%lx\n", type->name, type->cnt); - for_each_memblock_type(idx, type, rgn) { + for (idx = 0; idx < type->cnt; idx++) { + struct memblock_region *rgn = &type->regions[idx]; char nid_buf[32] = ""; base = rgn->base; @@ -2465,8 +2439,6 @@ static unsigned long __init free_low_memory_core_early(void) return count; } -static int reset_managed_pages_done __initdata; - static void __init reset_node_managed_pages(pg_data_t *pgdat) { struct zone *z; @@ -2475,17 +2447,12 @@ static void __init reset_node_managed_pages(pg_data_t *pgdat) atomic_long_set(&z->managed_pages, 0); } -void __init reset_all_zones_managed_pages(void) +static void __init reset_all_zones_managed_pages(void) { struct pglist_data *pgdat; - if (reset_managed_pages_done) - return; - for_each_online_pgdat(pgdat) reset_node_managed_pages(pgdat); - - reset_managed_pages_done = 1; } /** @@ -2700,15 +2667,10 @@ static int __init prepare_kho_fdt(void) static int __init reserve_mem_init(void) { - int err; - if (!kho_is_enabled() || !reserved_mem_count) return 0; - err = prepare_kho_fdt(); - if (err) - return err; - return err; + return prepare_kho_fdt(); } late_initcall(reserve_mem_init); @@ -2828,12 +2790,17 @@ static int __init reserve_mem(char *p) if (*p != ':') goto err_param; + if (!IS_ALIGNED(size, PAGE_SIZE) || !IS_ALIGNED(align, PAGE_SIZE)) { + pr_err("reserve_mem: size and align must be multiples of the page size\n"); + return -EINVAL; + } + /* * memblock_phys_alloc() doesn't like a zero size align, * but it is OK for this command to have it. */ - if (align < SMP_CACHE_BYTES) - align = SMP_CACHE_BYTES; + if (!align) + align = PAGE_SIZE; name = p + 1; len = strlen(name); diff --git a/mm/mm_init.c b/mm/mm_init.c index 2e55be145738..c18e722282e7 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -1243,6 +1243,10 @@ static unsigned long __init __absent_pages_in_range(int nid, unsigned long start_pfn, end_pfn; int i; + /* range is empty, nothing to do */ + if (!nr_absent) + return 0; + for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) { start_pfn = clamp(start_pfn, range_start_pfn, range_end_pfn); end_pfn = clamp(end_pfn, range_start_pfn, range_end_pfn); @@ -1264,22 +1268,9 @@ unsigned long __init absent_pages_in_range(unsigned long start_pfn, return __absent_pages_in_range(MAX_NUMNODES, start_pfn, end_pfn); } -/* Return the number of page frames in holes in a zone on a node */ -static unsigned long __init zone_absent_pages_in_node(int nid, - unsigned long zone_type, - unsigned long zone_start_pfn, - unsigned long zone_end_pfn) -{ - /* zone is empty, we don't have any absent pages */ - if (zone_start_pfn == zone_end_pfn) - return 0; - - return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); -} - /* * Return the number of pages a zone spans in a node, including holes - * present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node() + * present_pages = zone_spanned_pages_in_node() - __absent_pages_in_range() */ static unsigned long __init zone_spanned_pages_in_node(int nid, unsigned long zone_type, @@ -1369,9 +1360,8 @@ static void __init calculate_node_totalpages(struct pglist_data *pgdat, node_end_pfn, &zone_start_pfn, &zone_end_pfn); - absent = zone_absent_pages_in_node(pgdat->node_id, i, - zone_start_pfn, - zone_end_pfn); + absent = __absent_pages_in_range(pgdat->node_id, zone_start_pfn, + zone_end_pfn); real_size = spanned - absent; @@ -1636,7 +1626,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat) } void __init *memmap_alloc(phys_addr_t size, phys_addr_t align, - phys_addr_t min_addr, int nid, bool exact_nid) + phys_addr_t min_addr, int nid) { void *ptr; @@ -1644,14 +1634,8 @@ void __init *memmap_alloc(phys_addr_t size, phys_addr_t align, * Kmemleak will explicitly scan mem_map by traversing all valid * `struct *page`,so memblock does not need to be added to the scan list. */ - if (exact_nid) - ptr = memblock_alloc_exact_nid_raw(size, align, min_addr, - MEMBLOCK_ALLOC_NOLEAKTRACE, - nid); - else - ptr = memblock_alloc_try_nid_raw(size, align, min_addr, - MEMBLOCK_ALLOC_NOLEAKTRACE, - nid); + ptr = memblock_alloc_try_nid_raw(size, align, min_addr, + MEMBLOCK_ALLOC_NOLEAKTRACE, nid); if (ptr && size > 0) page_init_poison(ptr, size); @@ -1679,7 +1663,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat) end = ALIGN(pgdat_end_pfn(pgdat), MAX_ORDER_NR_PAGES); size = (end - start) * sizeof(struct page); map = memmap_alloc(size, SMP_CACHE_BYTES, MEMBLOCK_LOW_LIMIT, - pgdat->node_id, false); + pgdat->node_id); if (!map) panic("Failed to allocate %ld bytes for node %d memory map\n", size, pgdat->node_id); diff --git a/mm/mm_init.h b/mm/mm_init.h index 393006c1c6ef..0034e37dbabd 100644 --- a/mm/mm_init.h +++ b/mm/mm_init.h @@ -25,8 +25,8 @@ bool pfn_range_intersects_zones(int nid, unsigned long start_pfn, void memblock_free_pages(unsigned long pfn, unsigned int order); -void *memmap_alloc(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, - int nid, bool exact_nid); +void *memmap_alloc(phys_addr_t size, phys_addr_t align, + phys_addr_t min_addr, int nid); void memmap_init_range(unsigned long size, int nid, unsigned long zone, unsigned long start_pfn, unsigned long zone_end_pfn, diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 23b31bc4bf94..34be00c67009 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -62,7 +62,7 @@ void __ref *vmemmap_alloc_block(unsigned long size, int node) } return NULL; } else - return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), node, false); + return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), node); } static void * __meminit altmap_alloc_block_buf(unsigned long size, diff --git a/mm/sparse.c b/mm/sparse.c index b75921c622ed..36692b1dd733 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -215,7 +215,7 @@ struct page __init *__populate_section_memmap(unsigned long pfn, { const unsigned long size = PAGE_ALIGN(sizeof(struct page) * PAGES_PER_SECTION); - return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), nid, false); + return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), nid); } #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h index d586a510e6e1..bce7616cd7c4 100644 --- a/tools/include/linux/mm.h +++ b/tools/include/linux/mm.h @@ -30,7 +30,7 @@ static inline void *phys_to_virt(unsigned long address) #define virt_to_phys virt_to_phys static inline phys_addr_t virt_to_phys(volatile void *address) { - return (phys_addr_t)address; + return __pa(address); } static inline void totalram_pages_add(long count) diff --git a/tools/testing/memblock/Makefile b/tools/testing/memblock/Makefile index d80982ccdc20..20524fcbe3c7 100644 --- a/tools/testing/memblock/Makefile +++ b/tools/testing/memblock/Makefile @@ -7,7 +7,8 @@ CFLAGS += -I. -I../../include -Wall -O2 -fsanitize=address \ LDFLAGS += -fsanitize=address -fsanitize=undefined TARGETS = main TEST_OFILES = tests/alloc_nid_api.o tests/alloc_helpers_api.o tests/alloc_api.o \ - tests/basic_api.o tests/common.o tests/alloc_exact_nid_api.o + tests/basic_api.o tests/common.o tests/alloc_exact_nid_api.o \ + tests/alloc_low_api.o DEP_OFILES = memblock.o lib/slab.o mmzone.o slab.o cmdline.o OFILES = main.o $(DEP_OFILES) $(TEST_OFILES) EXTR_SRC = ../../../mm/memblock.c diff --git a/tools/testing/memblock/README b/tools/testing/memblock/README index b435f48d8a70..4ea293209548 100644 --- a/tools/testing/memblock/README +++ b/tools/testing/memblock/README @@ -67,13 +67,13 @@ memblock |-- tests | |-- alloc_api.(c|h) -- memblock_alloc tests | |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests +| |-- alloc_low_api.(c|h) -- memblock_alloc_low tests | |-- alloc_nid_api.(c|h) -- memblock_alloc_try_nid tests | |-- basic_api.(c|h) -- memblock_add/memblock_reserve/... tests | |-- common.(c|h) -- helper functions for resetting memblock; |-- main.c --------------. dummy physical memory definition |-- Makefile `- test runner |-- README -|-- TODO |-- .gitignore Simulating physical memory @@ -101,12 +101,10 @@ There's no need to explicitly free the dummy memory from memblock via memblock_free() call. The entry will be erased by reset_memblock_regions(), called at the beginning of each test. -Known issues -============ - -1. Tests for memblock_alloc_low() can't be easily implemented. The function uses - ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low - memory of the memory_block. +The simulator defines ARCH_LOW_ADDRESS_LIMIT in asm/dma.h using the midpoint +of the MEM_SIZE range registered by setup_memblock(). This leaves registered +memory both below and above the limit. The limit is the first address an +allocation must not use; an allocation's base plus its size may equal the limit. References ========== diff --git a/tools/testing/memblock/TODO b/tools/testing/memblock/TODO deleted file mode 100644 index c13ad0dae776..000000000000 --- a/tools/testing/memblock/TODO +++ /dev/null @@ -1,5 +0,0 @@ -TODO -===== - -1. Add tests for memblock_alloc_low() once the simulator can model - ARCH_LOW_ADDRESS_LIMIT against the low memory in memory_block diff --git a/tools/testing/memblock/asm/dma.h b/tools/testing/memblock/asm/dma.h index 13ff8e5d22ef..6607408dcf25 100644 --- a/tools/testing/memblock/asm/dma.h +++ b/tools/testing/memblock/asm/dma.h @@ -2,4 +2,10 @@ #ifndef _TOOLS_DMA_H #define _TOOLS_DMA_H +#include + +phys_addr_t dummy_physical_memory_low_limit(void); + +#define ARCH_LOW_ADDRESS_LIMIT dummy_physical_memory_low_limit() + #endif diff --git a/tools/testing/memblock/main.c b/tools/testing/memblock/main.c index 278f9dec5008..9a96e178551b 100644 --- a/tools/testing/memblock/main.c +++ b/tools/testing/memblock/main.c @@ -4,6 +4,7 @@ #include "tests/alloc_helpers_api.h" #include "tests/alloc_nid_api.h" #include "tests/alloc_exact_nid_api.h" +#include "tests/alloc_low_api.h" #include "tests/common.h" int main(int argc, char **argv) @@ -12,6 +13,7 @@ int main(int argc, char **argv) memblock_basic_checks(); memblock_alloc_checks(); memblock_alloc_helpers_checks(); + memblock_alloc_low_checks(); memblock_alloc_nid_checks(); memblock_alloc_exact_nid_checks(); diff --git a/tools/testing/memblock/tests/alloc_exact_nid_api.c b/tools/testing/memblock/tests/alloc_exact_nid_api.c index 0c46c73b5e04..52c63d011870 100644 --- a/tools/testing/memblock/tests/alloc_exact_nid_api.c +++ b/tools/testing/memblock/tests/alloc_exact_nid_api.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "alloc_exact_nid_api.h" -#include "alloc_nid_api.h" -#define FUNC_NAME "memblock_alloc_exact_nid_raw" +#define FUNC_NAME "memblock_alloc_range_nid(exact)" /* * contains the fraction of MEM_SIZE contained in each node in basis point @@ -19,6 +18,18 @@ static const unsigned int node_fractions[] = { 625, /* 1/16 */ }; +static void *alloc_range_exact_nid(phys_addr_t size, phys_addr_t align, + phys_addr_t min_addr, + phys_addr_t max_addr, int nid) +{ + phys_addr_t addr; + + addr = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid, + true); + + return addr ? phys_to_virt(addr) : NULL; +} + /* * A test that tries to allocate a memory region in a specific NUMA node that * has enough memory to allocate a region of the requested size. @@ -42,9 +53,8 @@ static int alloc_exact_nid_top_down_numa_simple_check(void) min_addr = memblock_start_of_DRAM(); max_addr = memblock_end_of_DRAM(); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_NE(allocated_ptr, NULL); ASSERT_MEM_NE(allocated_ptr, 0, size); @@ -98,9 +108,8 @@ static int alloc_exact_nid_top_down_numa_part_reserved_check(void) max_addr = memblock_end_of_DRAM(); memblock_reserve(r1.base, r1.size); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_NE(allocated_ptr, NULL); ASSERT_MEM_NE(allocated_ptr, 0, size); @@ -117,177 +126,6 @@ static int alloc_exact_nid_top_down_numa_part_reserved_check(void) return 0; } -/* - * A test that tries to allocate a memory region that spans over the min_addr - * and max_addr range and overlaps with two different nodes, where the first - * node is the requested node: - * - * min_addr - * | max_addr - * | | - * v v - * | +-----------------------+-----------+ | - * | | requested | node3 | | - * +-----------+-----------------------+-----------+--------------+ - * + + - * | +-----------+ | - * | | rgn | | - * +-----------------------+-----------+--------------------------+ - * - * Expect to drop the lower limit and allocate a memory region that ends at - * the end of the requested node. - */ -static int alloc_exact_nid_top_down_numa_split_range_low_check(void) -{ - int nid_req = 2; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - void *allocated_ptr = NULL; - phys_addr_t size = SZ_512; - phys_addr_t min_addr; - phys_addr_t max_addr; - phys_addr_t req_node_end; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - req_node_end = region_end(req_node); - min_addr = req_node_end - SZ_256; - max_addr = min_addr + size; - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, req_node_end - size); - ASSERT_LE(req_node->base, new_rgn->base); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - -/* - * A test that tries to allocate a memory region that spans over the min_addr - * and max_addr range and overlaps with two different nodes, where the requested - * node ends before min_addr: - * - * min_addr - * | max_addr - * | | - * v v - * | +---------------+ +-------------+---------+ | - * | | requested | | node1 | node2 | | - * +----+---------------+--------+-------------+---------+----------+ - * + + - * | +---------+ | - * | | rgn | | - * +----------+---------+-------------------------------------------+ - * - * Expect to drop the lower limit and allocate a memory region that ends at - * the end of the requested node. - */ -static int alloc_exact_nid_top_down_numa_no_overlap_split_check(void) -{ - int nid_req = 2; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - struct memblock_region *node2 = &memblock.memory.regions[6]; - void *allocated_ptr = NULL; - phys_addr_t size; - phys_addr_t min_addr; - phys_addr_t max_addr; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - size = SZ_512; - min_addr = node2->base - SZ_256; - max_addr = min_addr + size; - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, region_end(req_node) - size); - ASSERT_LE(req_node->base, new_rgn->base); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - -/* - * A test that tries to allocate memory within min_addr and max_add range when - * the requested node and the range do not overlap, and requested node ends - * before min_addr. The range overlaps with multiple nodes along node - * boundaries: - * - * min_addr - * | max_addr - * | | - * v v - * |-----------+ +----------+----...----+----------+ | - * | requested | | min node | ... | max node | | - * +-----------+-----------+----------+----...----+----------+------+ - * + + - * | +-----+ | - * | | rgn | | - * +-----+-----+----------------------------------------------------+ - * - * Expect to drop the lower limit and allocate a memory region that ends at - * the end of the requested node. - */ -static int alloc_exact_nid_top_down_numa_no_overlap_low_check(void) -{ - int nid_req = 0; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - struct memblock_region *min_node = &memblock.memory.regions[2]; - struct memblock_region *max_node = &memblock.memory.regions[5]; - void *allocated_ptr = NULL; - phys_addr_t size = SZ_64; - phys_addr_t max_addr; - phys_addr_t min_addr; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - min_addr = min_node->base; - max_addr = region_end(max_node); - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, region_end(req_node) - size); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - /* * A test that tries to allocate a memory region in a specific NUMA node that * has enough memory to allocate a region of the requested size. @@ -311,9 +149,8 @@ static int alloc_exact_nid_bottom_up_numa_simple_check(void) min_addr = memblock_start_of_DRAM(); max_addr = memblock_end_of_DRAM(); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_NE(allocated_ptr, NULL); ASSERT_MEM_NE(allocated_ptr, 0, size); @@ -369,9 +206,8 @@ static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void) total_size = size + r1.size; __memblock_reserve(r1.base, r1.size, nid_req, MEMBLOCK_RSRV_KERN); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_NE(allocated_ptr, NULL); ASSERT_MEM_NE(allocated_ptr, 0, size); @@ -388,178 +224,6 @@ static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void) return 0; } -/* - * A test that tries to allocate a memory region that spans over the min_addr - * and max_addr range and overlaps with two different nodes, where the first - * node is the requested node: - * - * min_addr - * | max_addr - * | | - * v v - * | +-----------------------+-----------+ | - * | | requested | node3 | | - * +-----------+-----------------------+-----------+--------------+ - * + + - * | +-----------+ | - * | | rgn | | - * +-----------+-----------+--------------------------------------+ - * - * Expect to drop the lower limit and allocate a memory region at the beginning - * of the requested node. - */ -static int alloc_exact_nid_bottom_up_numa_split_range_low_check(void) -{ - int nid_req = 2; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - void *allocated_ptr = NULL; - phys_addr_t size = SZ_512; - phys_addr_t min_addr; - phys_addr_t max_addr; - phys_addr_t req_node_end; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - req_node_end = region_end(req_node); - min_addr = req_node_end - SZ_256; - max_addr = min_addr + size; - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, req_node->base); - ASSERT_LE(region_end(new_rgn), req_node_end); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - -/* - * A test that tries to allocate a memory region that spans over the min_addr - * and max_addr range and overlaps with two different nodes, where the requested - * node ends before min_addr: - * - * min_addr - * | max_addr - * | | - * v v - * | +---------------+ +-------------+---------+ | - * | | requested | | node1 | node2 | | - * +----+---------------+--------+-------------+---------+---------+ - * + + - * | +---------+ | - * | | rgn | | - * +----+---------+------------------------------------------------+ - * - * Expect to drop the lower limit and allocate a memory region that starts at - * the beginning of the requested node. - */ -static int alloc_exact_nid_bottom_up_numa_no_overlap_split_check(void) -{ - int nid_req = 2; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - struct memblock_region *node2 = &memblock.memory.regions[6]; - void *allocated_ptr = NULL; - phys_addr_t size; - phys_addr_t min_addr; - phys_addr_t max_addr; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - size = SZ_512; - min_addr = node2->base - SZ_256; - max_addr = min_addr + size; - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, req_node->base); - ASSERT_LE(region_end(new_rgn), region_end(req_node)); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - -/* - * A test that tries to allocate memory within min_addr and max_add range when - * the requested node and the range do not overlap, and requested node ends - * before min_addr. The range overlaps with multiple nodes along node - * boundaries: - * - * min_addr - * | max_addr - * | | - * v v - * |-----------+ +----------+----...----+----------+ | - * | requested | | min node | ... | max node | | - * +-----------+-----------+----------+----...----+----------+------+ - * + + - * |-----+ | - * | rgn | | - * +-----+----------------------------------------------------------+ - * - * Expect to drop the lower limit and allocate a memory region that starts at - * the beginning of the requested node. - */ -static int alloc_exact_nid_bottom_up_numa_no_overlap_low_check(void) -{ - int nid_req = 0; - struct memblock_region *new_rgn = &memblock.reserved.regions[0]; - struct memblock_region *req_node = &memblock.memory.regions[nid_req]; - struct memblock_region *min_node = &memblock.memory.regions[2]; - struct memblock_region *max_node = &memblock.memory.regions[5]; - void *allocated_ptr = NULL; - phys_addr_t size = SZ_64; - phys_addr_t max_addr; - phys_addr_t min_addr; - - PREFIX_PUSH(); - setup_numa_memblock(node_fractions); - - min_addr = min_node->base; - max_addr = region_end(max_node); - - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); - - ASSERT_NE(allocated_ptr, NULL); - ASSERT_MEM_NE(allocated_ptr, 0, size); - - ASSERT_EQ(new_rgn->size, size); - ASSERT_EQ(new_rgn->base, req_node->base); - ASSERT_LE(region_end(new_rgn), region_end(req_node)); - - ASSERT_EQ(memblock.reserved.cnt, 1); - ASSERT_EQ(memblock.reserved.total_size, size); - - test_pass_pop(); - - return 0; -} - /* * A test that tries to allocate a memory region in a specific NUMA node that * does not have enough memory to allocate a region of the requested size: @@ -590,9 +254,8 @@ static int alloc_exact_nid_numa_small_node_generic_check(void) min_addr = memblock_start_of_DRAM(); max_addr = memblock_end_of_DRAM(); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); @@ -632,9 +295,8 @@ static int alloc_exact_nid_numa_node_reserved_generic_check(void) max_addr = memblock_end_of_DRAM(); memblock_reserve(req_node->base, req_node->size); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); @@ -680,9 +342,8 @@ static int alloc_exact_nid_numa_part_reserved_fail_generic_check(void) max_addr = memblock_end_of_DRAM(); memblock_reserve(r1.base, r1.size); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); @@ -721,9 +382,8 @@ static int alloc_exact_nid_numa_split_range_high_generic_check(void) min_addr = req_node->base - SZ_256; max_addr = min_addr + size; - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); @@ -764,9 +424,8 @@ static int alloc_exact_nid_numa_no_overlap_high_generic_check(void) min_addr = min_node->base; max_addr = region_end(max_node); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); @@ -803,9 +462,8 @@ static int alloc_exact_nid_numa_large_region_generic_check(void) min_addr = memblock_start_of_DRAM(); max_addr = memblock_end_of_DRAM(); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_EQ(allocated_ptr, NULL); test_pass_pop(); @@ -864,9 +522,8 @@ static int alloc_exact_nid_numa_reserved_full_merge_generic_check(void) __memblock_reserve(r1.base, r1.size, nid_req, MEMBLOCK_RSRV_KERN); __memblock_reserve(r2.base, r2.size, nid_req, MEMBLOCK_RSRV_KERN); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - nid_req); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, nid_req); ASSERT_NE(allocated_ptr, NULL); ASSERT_MEM_NE(allocated_ptr, 0, size); @@ -933,9 +590,8 @@ static int alloc_exact_nid_numa_split_all_reserved_generic_check(void) memblock_reserve(r1.base, r1.size); memblock_reserve(r2.base, r2.size); - allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES, - min_addr, max_addr, - NUMA_NO_NODE); + allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES, + min_addr, max_addr, NUMA_NO_NODE); ASSERT_EQ(allocated_ptr, NULL); @@ -967,38 +623,6 @@ static int alloc_exact_nid_numa_part_reserved_check(void) return 0; } -static int alloc_exact_nid_numa_split_range_low_check(void) -{ - test_print("\tRunning %s...\n", __func__); - memblock_set_bottom_up(false); - alloc_exact_nid_top_down_numa_split_range_low_check(); - memblock_set_bottom_up(true); - alloc_exact_nid_bottom_up_numa_split_range_low_check(); - - return 0; -} - -static int alloc_exact_nid_numa_no_overlap_split_check(void) -{ - test_print("\tRunning %s...\n", __func__); - memblock_set_bottom_up(false); - alloc_exact_nid_top_down_numa_no_overlap_split_check(); - memblock_set_bottom_up(true); - alloc_exact_nid_bottom_up_numa_no_overlap_split_check(); - - return 0; -} - -static int alloc_exact_nid_numa_no_overlap_low_check(void) -{ - test_print("\tRunning %s...\n", __func__); - memblock_set_bottom_up(false); - alloc_exact_nid_top_down_numa_no_overlap_low_check(); - memblock_set_bottom_up(true); - alloc_exact_nid_bottom_up_numa_no_overlap_low_check(); - - return 0; -} static int alloc_exact_nid_numa_small_node_check(void) { @@ -1078,9 +702,6 @@ int __memblock_alloc_exact_nid_numa_checks(void) alloc_exact_nid_numa_simple_check(); alloc_exact_nid_numa_part_reserved_check(); - alloc_exact_nid_numa_split_range_low_check(); - alloc_exact_nid_numa_no_overlap_split_check(); - alloc_exact_nid_numa_no_overlap_low_check(); alloc_exact_nid_numa_small_node_check(); alloc_exact_nid_numa_node_reserved_check(); @@ -1102,7 +723,6 @@ int memblock_alloc_exact_nid_checks(void) reset_memblock_attributes(); dummy_physical_memory_init(); - memblock_alloc_exact_nid_range_checks(); memblock_alloc_exact_nid_numa_checks(); dummy_physical_memory_cleanup(); diff --git a/tools/testing/memblock/tests/alloc_low_api.c b/tools/testing/memblock/tests/alloc_low_api.c new file mode 100644 index 000000000000..a117431f1f71 --- /dev/null +++ b/tools/testing/memblock/tests/alloc_low_api.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "alloc_low_api.h" +#include + +/* Allocate at the first or last aligned address below the low limit. */ +static int alloc_low_simple_check(void) +{ + struct memblock_region *rgn = &memblock.reserved.regions[0]; + phys_addr_t size = SZ_64; + phys_addr_t expected; + void *allocated_ptr; + + PREFIX_PUSH(); + setup_memblock(); + + /* Simulated physical RAM is not necessarily SMP_CACHE_BYTES aligned. */ + if (memblock_bottom_up()) + expected = ALIGN(memblock_start_of_DRAM(), SMP_CACHE_BYTES); + else + expected = ALIGN_DOWN(ARCH_LOW_ADDRESS_LIMIT - size, + SMP_CACHE_BYTES); + + allocated_ptr = memblock_alloc_low(size, SMP_CACHE_BYTES); + + ASSERT_NE(allocated_ptr, NULL); + ASSERT_EQ((phys_addr_t)(uintptr_t)allocated_ptr, expected); + ASSERT_MEM_EQ(allocated_ptr, 0, size); + ASSERT_EQ(rgn->base, expected); + ASSERT_EQ(rgn->size, size); + ASSERT_LE(region_end(rgn), ARCH_LOW_ADDRESS_LIMIT); + ASSERT_EQ(memblock.reserved.cnt, 1); + ASSERT_EQ(memblock.reserved.total_size, size); + + test_pass_pop(); + return 0; +} + +/* The last byte of the allocation is immediately below the low limit. */ +static int alloc_low_exact_limit_check(void) +{ + phys_addr_t limit = ARCH_LOW_ADDRESS_LIMIT; + phys_addr_t base = ALIGN_DOWN(limit - SZ_64, SMP_CACHE_BYTES); + phys_addr_t size = limit - base; + void *allocated_ptr; + + PREFIX_PUSH(); + setup_memblock(); + ASSERT_EQ(memblock_remove(memblock_start_of_DRAM(), + base - memblock_start_of_DRAM()), 0); + + allocated_ptr = memblock_alloc_low(size, SMP_CACHE_BYTES); + + ASSERT_NE(allocated_ptr, NULL); + ASSERT_EQ((phys_addr_t)(uintptr_t)allocated_ptr, base); + ASSERT_MEM_EQ(allocated_ptr, 0, size); + ASSERT_EQ(memblock.reserved.regions[0].base, base); + ASSERT_EQ(region_end(&memblock.reserved.regions[0]), limit); + ASSERT_EQ(memblock.reserved.cnt, 1); + ASSERT_EQ(memblock.reserved.total_size, size); + + test_pass_pop(); + return 0; +} + +/* + * There are size bytes below the limit, but aligning the start makes the + * allocation cross it. Memory above the limit must not satisfy the request. + */ +static int alloc_low_alignment_crosses_limit_check(void) +{ + phys_addr_t limit = ARCH_LOW_ADDRESS_LIMIT; + phys_addr_t base = ALIGN_DOWN(limit, SMP_CACHE_BYTES) - 1; + phys_addr_t size = limit - base; + void *allocated_ptr; + + PREFIX_PUSH(); + setup_memblock(); + ASSERT_EQ(memblock_remove(memblock_start_of_DRAM(), + base - memblock_start_of_DRAM()), 0); + + allocated_ptr = memblock_alloc_low(size, SMP_CACHE_BYTES); + + ASSERT_EQ(allocated_ptr, NULL); + ASSERT_EQ(memblock.reserved.cnt, 0); + ASSERT_EQ(memblock.reserved.total_size, 0); + ASSERT_MEM_EQ((void *)(uintptr_t)base, 1, memblock_end_of_DRAM() - base); + + test_pass_pop(); + return 0; +} + +/* Allocation must fail after reserving all low memory, with high memory free. */ +static int alloc_low_reserved_check(void) +{ + phys_addr_t limit = ARCH_LOW_ADDRESS_LIMIT; + phys_addr_t base = dummy_physical_memory_base(); + phys_addr_t size = SZ_64; + void *allocated_ptr; + + PREFIX_PUSH(); + setup_memblock(); + ASSERT_EQ(memblock_reserve(base, limit - base), 0); + + allocated_ptr = memblock_alloc_low(size, SMP_CACHE_BYTES); + + ASSERT_EQ(allocated_ptr, NULL); + ASSERT_EQ(memblock.reserved.cnt, 1); + ASSERT_EQ(memblock.reserved.regions[0].base, base); + ASSERT_EQ(memblock.reserved.regions[0].size, limit - base); + ASSERT_EQ(memblock.reserved.total_size, limit - base); + ASSERT_MEM_EQ((void *)(uintptr_t)base, 1, MEM_SIZE); + + allocated_ptr = memblock_alloc(size, SMP_CACHE_BYTES); + ASSERT_NE(allocated_ptr, NULL); + ASSERT_LE(limit, (phys_addr_t)(uintptr_t)allocated_ptr); + ASSERT_MEM_EQ(allocated_ptr, 0, size); + + test_pass_pop(); + return 0; +} + +static int alloc_low_checks(void) +{ + alloc_low_simple_check(); + alloc_low_exact_limit_check(); + alloc_low_alignment_crosses_limit_check(); + alloc_low_reserved_check(); + + return 0; +} + +int memblock_alloc_low_checks(void) +{ + prefix_reset(); + prefix_push("memblock_alloc_low"); + test_print("Running memblock_alloc_low tests...\n"); + + reset_memblock_attributes(); + dummy_physical_memory_init(); + + run_top_down(alloc_low_checks); + run_bottom_up(alloc_low_checks); + + dummy_physical_memory_cleanup(); + prefix_pop(); + + return 0; +} diff --git a/tools/testing/memblock/tests/alloc_low_api.h b/tools/testing/memblock/tests/alloc_low_api.h new file mode 100644 index 000000000000..2e3cbe336f5d --- /dev/null +++ b/tools/testing/memblock/tests/alloc_low_api.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _MEMBLOCK_ALLOC_LOW_H +#define _MEMBLOCK_ALLOC_LOW_H + +#include "common.h" + +int memblock_alloc_low_checks(void); + +#endif diff --git a/tools/testing/memblock/tests/alloc_nid_api.c b/tools/testing/memblock/tests/alloc_nid_api.c index c04923532159..3dd4c0bebc41 100644 --- a/tools/testing/memblock/tests/alloc_nid_api.c +++ b/tools/testing/memblock/tests/alloc_nid_api.c @@ -20,8 +20,6 @@ static const unsigned int node_fractions[] = { static inline const char * const get_memblock_alloc_nid_name(int flags) { - if (flags & TEST_F_EXACT) - return "memblock_alloc_exact_nid_raw"; if (flags & TEST_F_RAW) return "memblock_alloc_try_nid_raw"; return "memblock_alloc_try_nid"; @@ -32,15 +30,6 @@ static inline void *run_memblock_alloc_nid(phys_addr_t size, phys_addr_t min_addr, phys_addr_t max_addr, int nid) { - assert(!(alloc_nid_test_flags & TEST_F_EXACT) || - (alloc_nid_test_flags & TEST_F_RAW)); - /* - * TEST_F_EXACT should be checked before TEST_F_RAW since - * memblock_alloc_exact_nid_raw() performs raw allocations. - */ - if (alloc_nid_test_flags & TEST_F_EXACT) - return memblock_alloc_exact_nid_raw(size, align, min_addr, - max_addr, nid); if (alloc_nid_test_flags & TEST_F_RAW) return memblock_alloc_try_nid_raw(size, align, min_addr, max_addr, nid); @@ -2722,12 +2711,3 @@ int memblock_alloc_nid_checks(void) return 0; } - -int memblock_alloc_exact_nid_range_checks(void) -{ - alloc_nid_test_flags = (TEST_F_RAW | TEST_F_EXACT); - - memblock_alloc_nid_range_checks(); - - return 0; -} diff --git a/tools/testing/memblock/tests/alloc_nid_api.h b/tools/testing/memblock/tests/alloc_nid_api.h index 2b8cabacacb8..92d07d230e18 100644 --- a/tools/testing/memblock/tests/alloc_nid_api.h +++ b/tools/testing/memblock/tests/alloc_nid_api.h @@ -5,7 +5,6 @@ #include "common.h" int memblock_alloc_nid_checks(void); -int memblock_alloc_exact_nid_range_checks(void); int __memblock_alloc_nid_numa_checks(void); #ifdef CONFIG_NUMA diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c index 01e836fba488..47bcdcc115a5 100644 --- a/tools/testing/memblock/tests/basic_api.c +++ b/tools/testing/memblock/tests/basic_api.c @@ -1730,7 +1730,7 @@ static int memblock_free_simple_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); memblock_reserve(r2.base, r2.size); - memblock_free((void *)r1.base, r1.size); + memblock_phys_free(r1.base, r1.size); ASSERT_EQ(rgn->base, r2.base); ASSERT_EQ(rgn->size, r2.size); @@ -1778,7 +1778,7 @@ static int memblock_free_absent_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r2.base, r2.size); + memblock_phys_free(r2.base, r2.size); ASSERT_EQ(rgn->base, r1.base); ASSERT_EQ(rgn->size, r1.size); @@ -1832,7 +1832,7 @@ static int memblock_free_overlap_top_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r2.base, r2.size); + memblock_phys_free(r2.base, r2.size); ASSERT_EQ(rgn->base, r2.base + r2.size); ASSERT_EQ(rgn->size, total_size); @@ -1881,7 +1881,7 @@ static int memblock_free_overlap_bottom_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r2.base, r2.size); + memblock_phys_free(r2.base, r2.size); ASSERT_EQ(rgn->base, r1.base); ASSERT_EQ(rgn->size, total_size); @@ -1938,7 +1938,7 @@ static int memblock_free_within_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r2.base, r2.size); + memblock_phys_free(r2.base, r2.size); ASSERT_EQ(rgn1->base, r1.base); ASSERT_EQ(rgn1->size, r1_size); @@ -1976,7 +1976,7 @@ static int memblock_free_only_region_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r1.base, r1.size); + memblock_phys_free(r1.base, r1.size); ASSERT_EQ(rgn->base, 0); ASSERT_EQ(rgn->size, 0); @@ -2003,7 +2003,7 @@ static int memblock_free_only_region_check(void) * Expect the total size of reserved memory to be updated and the counter to * not be updated. */ -static int memblock_free_near_max_check(void) +static int memblock_phys_free_near_max_check(void) { struct memblock_region *rgn; phys_addr_t total_size; @@ -2026,7 +2026,7 @@ static int memblock_free_near_max_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); - memblock_free((void *)r2.base, r2.size); + memblock_phys_free(r2.base, r2.size); ASSERT_EQ(rgn->base, r1.base); ASSERT_EQ(rgn->size, total_size); @@ -2086,7 +2086,7 @@ static int memblock_free_overlap_two_check(void) reset_memblock_regions(); memblock_reserve(r1.base, r1.size); memblock_reserve(r2.base, r2.size); - memblock_free((void *)r3.base, r3.size); + memblock_phys_free(r3.base, r3.size); ASSERT_EQ(rgn1->base, r1.base); ASSERT_EQ(rgn1->size, new_r1_size); @@ -2114,7 +2114,7 @@ static int memblock_free_checks(void) memblock_free_overlap_bottom_check(); memblock_free_within_check(); memblock_free_only_region_check(); - memblock_free_near_max_check(); + memblock_phys_free_near_max_check(); memblock_free_overlap_two_check(); prefix_pop(); diff --git a/tools/testing/memblock/tests/common.c b/tools/testing/memblock/tests/common.c index 3250c8e5124b..2a248973eb4c 100644 --- a/tools/testing/memblock/tests/common.c +++ b/tools/testing/memblock/tests/common.c @@ -67,7 +67,7 @@ static inline void fill_memblock(void) void setup_memblock(void) { reset_memblock_regions(); - memblock_add((phys_addr_t)memory_block.base, MEM_SIZE); + memblock_add((phys_addr_t)(uintptr_t)memory_block.base, MEM_SIZE); fill_memblock(); } @@ -88,7 +88,7 @@ void setup_numa_memblock(const unsigned int node_fracs[]) int flags; reset_memblock_regions(); - base = (phys_addr_t)memory_block.base; + base = (phys_addr_t)(uintptr_t)memory_block.base; flags = (movable_node_is_enabled()) ? MEMBLOCK_NONE : MEMBLOCK_HOTPLUG; for (int i = 0; i < NUMA_NODES; i++) { @@ -115,7 +115,13 @@ void dummy_physical_memory_cleanup(void) phys_addr_t dummy_physical_memory_base(void) { - return (phys_addr_t)memory_block.base; + return (phys_addr_t)(uintptr_t)memory_block.base; +} + +phys_addr_t dummy_physical_memory_low_limit(void) +{ + /* The low limit is halfway through memory registered by setup_memblock(). */ + return dummy_physical_memory_base() + MEM_SIZE / 2; } static void usage(const char *prog) diff --git a/tools/testing/memblock/tests/common.h b/tools/testing/memblock/tests/common.h index e1138e06c903..c3cca972dcca 100644 --- a/tools/testing/memblock/tests/common.h +++ b/tools/testing/memblock/tests/common.h @@ -23,8 +23,6 @@ enum test_flags { TEST_F_NONE = 0x0, /* Perform raw allocations (no zeroing of memory). */ TEST_F_RAW = 0x1, - /* Perform allocations on the exact node specified. */ - TEST_F_EXACT = 0x2 }; /**