From f68c01000a6c3bddbf415b6e50a201196ec78358 Mon Sep 17 00:00:00 2001 From: Tianyi Chen Date: Thu, 10 Sep 2026 07:55:28 +0800 Subject: memblock tests: model the low allocation limit within dummy memory The simulator represents physical addresses using the address of its allocated buffer. That buffer can lie above the default ARCH_LOW_ADDRESS_LIMIT, preventing meaningful memblock_alloc_low() tests. Use the architecture override in asm/dma.h to place the limit halfway through the memory registered by setup_memblock(). Resolve the limit after allocating the buffer, leaving registered memory on both sides. Assisted-by: LLM Signed-off-by: Tianyi Chen Link: https://patch.msgid.link/f16c272cd52316b83c35d87987b4d8687c4a3182.1788997523.git.hi@tychen.cc Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/asm/dma.h | 6 ++++++ tools/testing/memblock/tests/common.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'tools/testing') 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/tests/common.c b/tools/testing/memblock/tests/common.c index 3250c8e5124b..ac032610a56e 100644 --- a/tools/testing/memblock/tests/common.c +++ b/tools/testing/memblock/tests/common.c @@ -118,6 +118,12 @@ phys_addr_t dummy_physical_memory_base(void) return (phys_addr_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) { BUILD_BUG_ON(ARRAY_SIZE(help_opts) != ARRAY_SIZE(long_opts) - 1); -- cgit v1.2.3 From 2345d7e354e84c140de225022a38754eab499a94 Mon Sep 17 00:00:00 2001 From: Tianyi Chen Date: Thu, 10 Sep 2026 07:55:33 +0800 Subject: memblock tests: cover allocations below the low address limit Add memblock_alloc_low() coverage using the simulator's low address limit. Exercise aligned allocation, an allocation whose last byte is immediately below the limit, an alignment constraint that prevents fitting below it, and fully reserved low memory with high memory still available. Run each case with bottom-up and top-down allocation. Check zeroing and reserved-region accounting as well as returned addresses. Verify that an unrestricted allocation can use the free high memory after the low allocation fails. Document the simulated limit and remove the completed TODO. Assisted-by: LLM Signed-off-by: Tianyi Chen Link: https://patch.msgid.link/142ab1025fd1e4b5dcd2a1591b964626ebce9d23.1788997523.git.hi@tychen.cc Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/Makefile | 3 +- tools/testing/memblock/README | 12 +-- tools/testing/memblock/TODO | 5 - tools/testing/memblock/main.c | 2 + tools/testing/memblock/tests/alloc_low_api.c | 148 +++++++++++++++++++++++++++ tools/testing/memblock/tests/alloc_low_api.h | 9 ++ 6 files changed, 166 insertions(+), 13 deletions(-) delete mode 100644 tools/testing/memblock/TODO create mode 100644 tools/testing/memblock/tests/alloc_low_api.c create mode 100644 tools/testing/memblock/tests/alloc_low_api.h (limited to 'tools/testing') 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/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_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 -- cgit v1.2.3 From 9357596afac61154e7f54048c0add9f1293b9eba Mon Sep 17 00:00:00 2001 From: Tianyi Chen Date: Wed, 23 Sep 2026 11:31:23 +0900 Subject: memblock tests: use physical addresses for region removal With BUILD=32, phys_addr_t remains 64-bit while pointers are 32-bit. Casting the address near PHYS_ADDR_MAX to void * truncates it before memblock_free() converts it back with __pa(). The reserved region is therefore left unchanged and memblock_free_near_max_check() fails. Use memblock_phys_free() for all synthetic physical ranges in the basic API tests. This also removes the integer-to-pointer cast warnings from the other removal checks. Retain the checks that freeing past PHYS_ADDR_MAX clips the removed region. Assisted-by: LLM Signed-off-by: Tianyi Chen Link: https://patch.msgid.link/20260923023126.1910311-2-hi@tychen.cc Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/tests/basic_api.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'tools/testing') 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(); -- cgit v1.2.3 From 6957416ae43de1830174f527b5b8cf737401a8dd Mon Sep 17 00:00:00 2001 From: Tianyi Chen Date: Wed, 23 Sep 2026 11:31:24 +0900 Subject: memblock tests: zero-extend simulated memory addresses Converting a 32-bit pointer directly to the 64-bit phys_addr_t can sign-extend it when BUILD=32 is used. A dummy allocation above 2 GiB then gets registered at an address different from its unsigned pointer value. The low-address tests compare that value against the registered range and fail once the earlier maximum-address free test is fixed. Convert through uintptr_t when registering and reporting dummy memory. This preserves the pointer bits and agrees with the simulator __pa() conversion and the allocation tests. Assisted-by: LLM Signed-off-by: Tianyi Chen Link: https://patch.msgid.link/20260923023126.1910311-3-hi@tychen.cc Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/tests/common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/testing') diff --git a/tools/testing/memblock/tests/common.c b/tools/testing/memblock/tests/common.c index ac032610a56e..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,7 @@ 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) -- cgit v1.2.3 From fba3e86fb848f79c4573243affcd7d79d378958d Mon Sep 17 00:00:00 2001 From: Kaitao Cheng Date: Sat, 19 Sep 2026 21:53:26 +0800 Subject: memblock tests: Move exact nid tests to memblock_alloc_range_nid() After memmap_alloc() stopped requesting allocations from an exact NUMA node, memblock_alloc_exact_nid_raw() no longer has any in-kernel users and is being removed. Preserve coverage of exact-node allocation by converting the applicable NUMA tests to call memblock_alloc_range_nid() with exact_nid set. Remove the tests that depend on memblock_alloc_internal() retrying below min_addr, as memblock_alloc_range_nid() treats its address range as a hard constraint. Remove the now-unused TEST_F_EXACT support from the shared allocation tests. Suggested-by: Lorenzo Stoakes Signed-off-by: Kaitao Cheng Link: https://patch.msgid.link/20260919135327.74089-3-kaitao.cheng@linux.dev Signed-off-by: Mike Rapoport (Microsoft) --- tools/testing/memblock/tests/alloc_exact_nid_api.c | 454 ++------------------- tools/testing/memblock/tests/alloc_nid_api.c | 20 - tools/testing/memblock/tests/alloc_nid_api.h | 1 - tools/testing/memblock/tests/common.h | 2 - 4 files changed, 37 insertions(+), 440 deletions(-) (limited to 'tools/testing') 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_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/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 }; /** -- cgit v1.2.3