summaryrefslogtreecommitdiff
path: root/tools/testing/memblock
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/memblock')
-rw-r--r--tools/testing/memblock/Makefile3
-rw-r--r--tools/testing/memblock/README12
-rw-r--r--tools/testing/memblock/TODO5
-rw-r--r--tools/testing/memblock/asm/dma.h6
-rw-r--r--tools/testing/memblock/internal.h2
-rw-r--r--tools/testing/memblock/main.c2
-rw-r--r--tools/testing/memblock/tests/alloc_exact_nid_api.c454
-rw-r--r--tools/testing/memblock/tests/alloc_low_api.c148
-rw-r--r--tools/testing/memblock/tests/alloc_low_api.h9
-rw-r--r--tools/testing/memblock/tests/alloc_nid_api.c20
-rw-r--r--tools/testing/memblock/tests/alloc_nid_api.h1
-rw-r--r--tools/testing/memblock/tests/basic_api.c20
-rw-r--r--tools/testing/memblock/tests/common.c12
-rw-r--r--tools/testing/memblock/tests/common.h2
14 files changed, 229 insertions, 467 deletions
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 <linux/types.h>
+
+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/internal.h b/tools/testing/memblock/internal.h
index f1974e009013..ba4d1c02fde5 100644
--- a/tools/testing/memblock/internal.h
+++ b/tools/testing/memblock/internal.h
@@ -46,7 +46,7 @@ static inline bool __is_kernel(unsigned long addr)
#define __SetPageReserved(p) ((void)(p))
-static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size)
+static inline bool kho_bootmem_overlap(phys_addr_t phys, size_t size)
{
return false;
}
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);
@@ -118,177 +127,6 @@ static int alloc_exact_nid_top_down_numa_part_reserved_check(void)
}
/*
- * 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.
* Expect to allocate an aligned region at the beginning of the requested node.
@@ -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);
@@ -389,178 +225,6 @@ static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void)
}
/*
- * 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 <linux/align.h>
+
+/* 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
};
/**