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 @@
# Simulate CONFIG_NUMA=y
ifeq ($(NUMA), 1)
CFLAGS += -D CONFIG_NUMA
CFLAGS += -D CONFIG_NUMA -D CONFIG_NODES_SHIFT=4
endif
# Use 32 bit physical addresses.
......
This diff is collapsed.
......@@ -19,22 +19,18 @@ static int alloc_from_simple_generic_check(void)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
char *b;
PREFIX_PUSH();
phys_addr_t size = SZ_16;
phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock();
min_addr = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
b = (char *)allocated_ptr;
ASSERT_NE(allocated_ptr, NULL);
ASSERT_EQ(*b, 0);
ASSERT_MEM_EQ(allocated_ptr, 0, size);
ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr);
......@@ -66,23 +62,19 @@ static int alloc_from_misaligned_generic_check(void)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
char *b;
PREFIX_PUSH();
phys_addr_t size = SZ_32;
phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock();
/* A misaligned address */
min_addr = memblock_end_of_DRAM() - (SMP_CACHE_BYTES * 2 - 1);
allocated_ptr = memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr);
b = (char *)allocated_ptr;
ASSERT_NE(allocated_ptr, NULL);
ASSERT_EQ(*b, 0);
ASSERT_MEM_EQ(allocated_ptr, 0, size);
ASSERT_EQ(rgn->size, size);
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)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t size = SZ_32;
phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock();
/* 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)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64;
phys_addr_t r2_size = SZ_2;
phys_addr_t total_size = r1_size + r2_size;
phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock();
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)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr;
phys_addr_t start_addr;
PREFIX_PUSH();
setup_memblock();
start_addr = (phys_addr_t)memblock_start_of_DRAM();
......@@ -249,12 +235,10 @@ static int alloc_from_bottom_up_high_addr_check(void)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t size = SZ_32;
phys_addr_t min_addr;
PREFIX_PUSH();
setup_memblock();
/* 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)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr;
phys_addr_t r2_size;
PREFIX_PUSH();
setup_memblock();
min_addr = memblock_start_of_DRAM() + SZ_128;
......@@ -331,13 +313,11 @@ static int alloc_from_bottom_up_min_addr_cap_check(void)
{
struct memblock_region *rgn = &memblock.reserved.regions[0];
void *allocated_ptr = NULL;
PREFIX_PUSH();
phys_addr_t r1_size = SZ_64;
phys_addr_t min_addr;
phys_addr_t start_addr;
PREFIX_PUSH();
setup_memblock();
start_addr = (phys_addr_t)memblock_start_of_DRAM();
......@@ -361,10 +341,8 @@ static int alloc_from_bottom_up_min_addr_cap_check(void)
static int alloc_from_simple_check(void)
{
test_print("\tRunning %s...\n", __func__);
memblock_set_bottom_up(false);
alloc_from_simple_generic_check();
memblock_set_bottom_up(true);
alloc_from_simple_generic_check();
run_top_down(alloc_from_simple_generic_check);
run_bottom_up(alloc_from_simple_generic_check);
return 0;
}
......@@ -372,10 +350,8 @@ static int alloc_from_simple_check(void)
static int alloc_from_misaligned_check(void)
{
test_print("\tRunning %s...\n", __func__);
memblock_set_bottom_up(false);
alloc_from_misaligned_generic_check();
memblock_set_bottom_up(true);
alloc_from_misaligned_generic_check();
run_top_down(alloc_from_misaligned_generic_check);
run_bottom_up(alloc_from_misaligned_generic_check);
return 0;
}
......
......@@ -5,5 +5,21 @@
#include "common.h"
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
This diff is collapsed.
......@@ -9,19 +9,22 @@
#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
#define PREFIXES_MAX 15
#define DELIM ": "
#define BASIS 10000
static struct test_memory memory_block;
static const char __maybe_unused *prefixes[PREFIXES_MAX];
static int __maybe_unused nr_prefixes;
static const char *short_opts = "mv";
static const char *short_opts = "hmv";
static const struct option long_opts[] = {
{"help", 0, NULL, 'h'},
{"movable-node", 0, NULL, 'm'},
{"verbose", 0, NULL, 'v'},
{NULL, 0, NULL, 0}
};
static const char * const help_opts[] = {
"display this help message and exit",
"disallow allocations from regions marked as hotplugged\n\t\t\t"
"by simulating enabling the \"movable_node\" kernel\n\t\t\t"
"parameter",
......@@ -58,16 +61,53 @@ void reset_memblock_attributes(void)
memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
}
static inline void fill_memblock(void)
{
memset(memory_block.base, 1, MEM_SIZE);
}
void setup_memblock(void)
{
reset_memblock_regions();
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)
{
memory_block.base = malloc(MEM_SIZE);
assert(memory_block.base);
fill_memblock();
}
void dummy_physical_memory_cleanup(void)
......
......@@ -10,13 +10,22 @@
#include <linux/printk.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():
* Check the condition
* @_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 { \
if ((_expected) != (_seen)) \
......@@ -28,7 +37,8 @@
* ASSERT_NE():
* Check the condition
* @_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 { \
if ((_expected) == (_seen)) \
......@@ -40,7 +50,8 @@
* ASSERT_LT():
* Check the condition
* @_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 { \
if ((_expected) >= (_seen)) \
......@@ -48,6 +59,43 @@
assert((_expected) < (_seen)); \
} 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__)
/*
......@@ -65,9 +113,15 @@ struct region {
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_attributes(void);
void setup_memblock(void);
void setup_numa_memblock(const unsigned int node_fracs[]);
void dummy_physical_memory_init(void);
void dummy_physical_memory_cleanup(void);
void parse_args(int argc, char **argv);
......@@ -85,4 +139,28 @@ static inline void test_pass_pop(void)
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
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