Commit 49da0700 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'memblock-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock

Pull memblock updates from Mike Rapoport:
 "Test suite improvements:

   - Added verification that memblock allocations zero the allocated
     memory

   - Added more test cases for memblock_add(), memblock_remove(),
     memblock_reserve() and memblock_free()

   - Added tests for memblock_*_raw() family

   - Added tests for NUMA-aware allocations in memblock_alloc_try_nid()
     and memblock_alloc_try_nid_raw()"

* tag 'memblock-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock:
  memblock tests: add generic NUMA tests for memblock_alloc_try_nid*
  memblock tests: add bottom-up NUMA tests for memblock_alloc_try_nid*
  memblock tests: add top-down NUMA tests for memblock_alloc_try_nid*
  memblock tests: add simulation of physical memory with multiple NUMA nodes
  memblock_tests: move variable declarations to single block
  memblock tests: remove 'cleared' from comment blocks
  memblock tests: add tests for memblock_trim_memory
  memblock tests: add tests for memblock_*bottom_up functions
  memblock tests: update alloc_nid_api to test memblock_alloc_try_nid_raw
  memblock tests: update alloc_api to test memblock_alloc_raw
  memblock tests: add additional tests for basic api and memblock_alloc
  memblock tests: add labels to verbose output for generic alloc tests
  memblock tests: update zeroed memory check for memblock_alloc_* tests
  memblock tests: update tests to check if memblock_alloc zeroed memory
  memblock tests: update reference to obsolete build option in comments
  memblock tests: add command line help option
parents f311d498 3e4519b7
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Simulate CONFIG_NUMA=y # Simulate CONFIG_NUMA=y
ifeq ($(NUMA), 1) ifeq ($(NUMA), 1)
CFLAGS += -D CONFIG_NUMA CFLAGS += -D CONFIG_NUMA -D CONFIG_NODES_SHIFT=4
endif endif
# Use 32 bit physical addresses. # Use 32 bit physical addresses.
......
This diff is collapsed.
...@@ -19,22 +19,18 @@ static int alloc_from_simple_generic_check(void) ...@@ -19,22 +19,18 @@ static int alloc_from_simple_generic_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
char *b;
PREFIX_PUSH();
phys_addr_t size = SZ_16; phys_addr_t size = SZ_16;
phys_addr_t min_addr; phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES; min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr); allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
b = (char *)allocated_ptr;
ASSERT_NE(allocated_ptr, NULL); ASSERT_NE(allocated_ptr, NULL);
ASSERT_EQ(*b, 0); ASSERT_MEM_EQ(allocated_ptr, 0, size);
ASSERT_EQ(rgn->size, size); ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr); ASSERT_EQ(rgn->base, min_addr);
...@@ -66,23 +62,19 @@ static int alloc_from_misaligned_generic_check(void) ...@@ -66,23 +62,19 @@ static int alloc_from_misaligned_generic_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
char *b;
PREFIX_PUSH();
phys_addr_t size = SZ_32; phys_addr_t size = SZ_32;
phys_addr_t min_addr; phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
/* A misaligned address */ /* A misaligned address */
min_addr = memblock_end_of_DRAM() - (SMP_CACHE_BYTES * 2 - 1); min_addr = memblock_end_of_DRAM() - (SMP_CACHE_BYTES * 2 - 1);
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr); allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
b = (char *)allocated_ptr;
ASSERT_NE(allocated_ptr, NULL); ASSERT_NE(allocated_ptr, NULL);
ASSERT_EQ(*b, 0); ASSERT_MEM_EQ(allocated_ptr, 0, size);
ASSERT_EQ(rgn->size, size); ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - SMP_CACHE_BYTES); ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - SMP_CACHE_BYTES);
...@@ -117,12 +109,10 @@ static int alloc_from_top_down_high_addr_check(void) ...@@ -117,12 +109,10 @@ static int alloc_from_top_down_high_addr_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t size = SZ_32; phys_addr_t size = SZ_32;
phys_addr_t min_addr; phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
/* The address is too close to the end of the memory */ /* The address is too close to the end of the memory */
...@@ -162,14 +152,12 @@ static int alloc_from_top_down_no_space_above_check(void) ...@@ -162,14 +152,12 @@ static int alloc_from_top_down_no_space_above_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64; phys_addr_t r1_size = SZ_64;
phys_addr_t r2_size = SZ_2; phys_addr_t r2_size = SZ_2;
phys_addr_t total_size = r1_size + r2_size; phys_addr_t total_size = r1_size + r2_size;
phys_addr_t min_addr; phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2;
...@@ -201,13 +189,11 @@ static int alloc_from_top_down_min_addr_cap_check(void) ...@@ -201,13 +189,11 @@ static int alloc_from_top_down_min_addr_cap_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64; phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr; phys_addr_t min_addr;
phys_addr_t start_addr; phys_addr_t start_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
start_addr = (phys_addr_t)memblock_start_of_DRAM(); start_addr = (phys_addr_t)memblock_start_of_DRAM();
...@@ -249,12 +235,10 @@ static int alloc_from_bottom_up_high_addr_check(void) ...@@ -249,12 +235,10 @@ static int alloc_from_bottom_up_high_addr_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t size = SZ_32; phys_addr_t size = SZ_32;
phys_addr_t min_addr; phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
/* The address is too close to the end of the memory */ /* The address is too close to the end of the memory */
...@@ -293,13 +277,11 @@ static int alloc_from_bottom_up_no_space_above_check(void) ...@@ -293,13 +277,11 @@ static int alloc_from_bottom_up_no_space_above_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64; phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr; phys_addr_t min_addr;
phys_addr_t r2_size; phys_addr_t r2_size;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
min_addr = memblock_start_of_DRAM() + SZ_128; min_addr = memblock_start_of_DRAM() + SZ_128;
...@@ -331,13 +313,11 @@ static int alloc_from_bottom_up_min_addr_cap_check(void) ...@@ -331,13 +313,11 @@ static int alloc_from_bottom_up_min_addr_cap_check(void)
{ {
struct memblock_region *rgn = &memblock.reserved.regions[0]; struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL; void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64; phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr; phys_addr_t min_addr;
phys_addr_t start_addr; phys_addr_t start_addr;
PREFIX_PUSH();
setup_memblock(); setup_memblock();
start_addr = (phys_addr_t)memblock_start_of_DRAM(); start_addr = (phys_addr_t)memblock_start_of_DRAM();
...@@ -361,10 +341,8 @@ static int alloc_from_bottom_up_min_addr_cap_check(void) ...@@ -361,10 +341,8 @@ static int alloc_from_bottom_up_min_addr_cap_check(void)
static int alloc_from_simple_check(void) static int alloc_from_simple_check(void)
{ {
test_print("\tRunning %s...\n", __func__); test_print("\tRunning %s...\n", __func__);
memblock_set_bottom_up(false); run_top_down(alloc_from_simple_generic_check);
alloc_from_simple_generic_check(); run_bottom_up(alloc_from_simple_generic_check);
memblock_set_bottom_up(true);
alloc_from_simple_generic_check();
return 0; return 0;
} }
...@@ -372,10 +350,8 @@ static int alloc_from_simple_check(void) ...@@ -372,10 +350,8 @@ static int alloc_from_simple_check(void)
static int alloc_from_misaligned_check(void) static int alloc_from_misaligned_check(void)
{ {
test_print("\tRunning %s...\n", __func__); test_print("\tRunning %s...\n", __func__);
memblock_set_bottom_up(false); run_top_down(alloc_from_misaligned_generic_check);
alloc_from_misaligned_generic_check(); run_bottom_up(alloc_from_misaligned_generic_check);
memblock_set_bottom_up(true);
alloc_from_misaligned_generic_check();
return 0; return 0;
} }
......
...@@ -5,5 +5,21 @@ ...@@ -5,5 +5,21 @@
#include "common.h" #include "common.h"
int memblock_alloc_nid_checks(void); int memblock_alloc_nid_checks(void);
int __memblock_alloc_nid_numa_checks(void);
#ifdef CONFIG_NUMA
static inline int memblock_alloc_nid_numa_checks(void)
{
__memblock_alloc_nid_numa_checks();
return 0;
}
#else
static inline int memblock_alloc_nid_numa_checks(void)
{
return 0;
}
#endif /* CONFIG_NUMA */
#endif #endif
This diff is collapsed.
...@@ -9,19 +9,22 @@ ...@@ -9,19 +9,22 @@
#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS #define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
#define PREFIXES_MAX 15 #define PREFIXES_MAX 15
#define DELIM ": " #define DELIM ": "
#define BASIS 10000
static struct test_memory memory_block; static struct test_memory memory_block;
static const char __maybe_unused *prefixes[PREFIXES_MAX]; static const char __maybe_unused *prefixes[PREFIXES_MAX];
static int __maybe_unused nr_prefixes; static int __maybe_unused nr_prefixes;
static const char *short_opts = "mv"; static const char *short_opts = "hmv";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{"help", 0, NULL, 'h'},
{"movable-node", 0, NULL, 'm'}, {"movable-node", 0, NULL, 'm'},
{"verbose", 0, NULL, 'v'}, {"verbose", 0, NULL, 'v'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
static const char * const help_opts[] = { static const char * const help_opts[] = {
"display this help message and exit",
"disallow allocations from regions marked as hotplugged\n\t\t\t" "disallow allocations from regions marked as hotplugged\n\t\t\t"
"by simulating enabling the \"movable_node\" kernel\n\t\t\t" "by simulating enabling the \"movable_node\" kernel\n\t\t\t"
"parameter", "parameter",
...@@ -58,16 +61,53 @@ void reset_memblock_attributes(void) ...@@ -58,16 +61,53 @@ void reset_memblock_attributes(void)
memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE; memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
} }
static inline void fill_memblock(void)
{
memset(memory_block.base, 1, MEM_SIZE);
}
void setup_memblock(void) void setup_memblock(void)
{ {
reset_memblock_regions(); reset_memblock_regions();
memblock_add((phys_addr_t)memory_block.base, MEM_SIZE); memblock_add((phys_addr_t)memory_block.base, MEM_SIZE);
fill_memblock();
}
/**
* setup_numa_memblock:
* Set up a memory layout with multiple NUMA nodes in a previously allocated
* dummy physical memory.
* @node_fracs: an array representing the fraction of MEM_SIZE contained in
* each node in basis point units (one hundredth of 1% or 1/10000).
* For example, if node 0 should contain 1/8 of MEM_SIZE,
* node_fracs[0] = 1250.
*
* The nids will be set to 0 through NUMA_NODES - 1.
*/
void setup_numa_memblock(const unsigned int node_fracs[])
{
phys_addr_t base;
int flags;
reset_memblock_regions();
base = (phys_addr_t)memory_block.base;
flags = (movable_node_is_enabled()) ? MEMBLOCK_NONE : MEMBLOCK_HOTPLUG;
for (int i = 0; i < NUMA_NODES; i++) {
assert(node_fracs[i] <= BASIS);
phys_addr_t size = MEM_SIZE * node_fracs[i] / BASIS;
memblock_add_node(base, size, i, flags);
base += size;
}
fill_memblock();
} }
void dummy_physical_memory_init(void) void dummy_physical_memory_init(void)
{ {
memory_block.base = malloc(MEM_SIZE); memory_block.base = malloc(MEM_SIZE);
assert(memory_block.base); assert(memory_block.base);
fill_memblock();
} }
void dummy_physical_memory_cleanup(void) void dummy_physical_memory_cleanup(void)
......
...@@ -11,12 +11,21 @@ ...@@ -11,12 +11,21 @@
#include <../selftests/kselftest.h> #include <../selftests/kselftest.h>
#define MEM_SIZE SZ_16K #define MEM_SIZE SZ_16K
#define NUMA_NODES 8
enum test_flags {
/* No special request. */
TEST_F_NONE = 0x0,
/* Perform raw allocations (no zeroing of memory). */
TEST_F_RAW = 0x1,
};
/** /**
* ASSERT_EQ(): * ASSERT_EQ():
* Check the condition * Check the condition
* @_expected == @_seen * @_expected == @_seen
* If false, print failed test message (if in VERBOSE mode) and then assert * If false, print failed test message (if running with --verbose) and then
* assert.
*/ */
#define ASSERT_EQ(_expected, _seen) do { \ #define ASSERT_EQ(_expected, _seen) do { \
if ((_expected) != (_seen)) \ if ((_expected) != (_seen)) \
...@@ -28,7 +37,8 @@ ...@@ -28,7 +37,8 @@
* ASSERT_NE(): * ASSERT_NE():
* Check the condition * Check the condition
* @_expected != @_seen * @_expected != @_seen
* If false, print failed test message (if in VERBOSE mode) and then assert * If false, print failed test message (if running with --verbose) and then
* assert.
*/ */
#define ASSERT_NE(_expected, _seen) do { \ #define ASSERT_NE(_expected, _seen) do { \
if ((_expected) == (_seen)) \ if ((_expected) == (_seen)) \
...@@ -40,7 +50,8 @@ ...@@ -40,7 +50,8 @@
* ASSERT_LT(): * ASSERT_LT():
* Check the condition * Check the condition
* @_expected < @_seen * @_expected < @_seen
* If false, print failed test message (if in VERBOSE mode) and then assert * If false, print failed test message (if running with --verbose) and then
* assert.
*/ */
#define ASSERT_LT(_expected, _seen) do { \ #define ASSERT_LT(_expected, _seen) do { \
if ((_expected) >= (_seen)) \ if ((_expected) >= (_seen)) \
...@@ -48,6 +59,43 @@ ...@@ -48,6 +59,43 @@
assert((_expected) < (_seen)); \ assert((_expected) < (_seen)); \
} while (0) } while (0)
/**
* ASSERT_LE():
* Check the condition
* @_expected <= @_seen
* If false, print failed test message (if running with --verbose) and then
* assert.
*/
#define ASSERT_LE(_expected, _seen) do { \
if ((_expected) > (_seen)) \
test_fail(); \
assert((_expected) <= (_seen)); \
} while (0)
/**
* ASSERT_MEM_EQ():
* Check that the first @_size bytes of @_seen are all equal to @_expected.
* If false, print failed test message (if running with --verbose) and then
* assert.
*/
#define ASSERT_MEM_EQ(_seen, _expected, _size) do { \
for (int _i = 0; _i < (_size); _i++) { \
ASSERT_EQ(((char *)_seen)[_i], (_expected)); \
} \
} while (0)
/**
* ASSERT_MEM_NE():
* Check that none of the first @_size bytes of @_seen are equal to @_expected.
* If false, print failed test message (if running with --verbose) and then
* assert.
*/
#define ASSERT_MEM_NE(_seen, _expected, _size) do { \
for (int _i = 0; _i < (_size); _i++) { \
ASSERT_NE(((char *)_seen)[_i], (_expected)); \
} \
} while (0)
#define PREFIX_PUSH() prefix_push(__func__) #define PREFIX_PUSH() prefix_push(__func__)
/* /*
...@@ -65,9 +113,15 @@ struct region { ...@@ -65,9 +113,15 @@ struct region {
phys_addr_t size; phys_addr_t size;
}; };
static inline phys_addr_t __maybe_unused region_end(struct memblock_region *rgn)
{
return rgn->base + rgn->size;
}
void reset_memblock_regions(void); void reset_memblock_regions(void);
void reset_memblock_attributes(void); void reset_memblock_attributes(void);
void setup_memblock(void); void setup_memblock(void);
void setup_numa_memblock(const unsigned int node_fracs[]);
void dummy_physical_memory_init(void); void dummy_physical_memory_init(void);
void dummy_physical_memory_cleanup(void); void dummy_physical_memory_cleanup(void);
void parse_args(int argc, char **argv); void parse_args(int argc, char **argv);
...@@ -85,4 +139,28 @@ static inline void test_pass_pop(void) ...@@ -85,4 +139,28 @@ static inline void test_pass_pop(void)
prefix_pop(); prefix_pop();
} }
static inline void run_top_down(int (*func)())
{
memblock_set_bottom_up(false);
prefix_push("top-down");
func();
prefix_pop();
}
static inline void run_bottom_up(int (*func)())
{
memblock_set_bottom_up(true);
prefix_push("bottom-up");
func();
prefix_pop();
}
static inline void assert_mem_content(void *mem, int size, int flags)
{
if (flags & TEST_F_RAW)
ASSERT_MEM_NE(mem, 0, size);
else
ASSERT_MEM_EQ(mem, 0, size);
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment