2022-08-19 08:57:20

by Rebecca Mckeever

[permalink] [raw]
Subject: [PATCH v2 0/8] memblock tests: update and extend memblock simulator

These patches update existing tests in memblock simulator, add
additional tests for memblock functions that are already being tested,
and add test coverage for additional memblock functions.

Updated tests for:
- memblock_alloc()
- memblock_alloc_try_nid()
- memblock_alloc_from()

The updates to memblock_alloc() tests include the addition of an assert
that checks whether the entire chunk of allocated memory is cleared. For
memblock_alloc_try_nid() and memblock_alloc_from(), the assert that checks
whether the allocated memory is cleared now checks the entire chunk of
allocated memory instead of just the first byte. To make this more robust,
setup_memblock() and dummy_physical_memory_init() fill the entire MEM_SIZE
simulated physical memory with nonzero values by calling fill_memblock().
setup_memblock() is called at the beginning of most tests for
memblock_alloc() functions.

Additional tests for:
- memblock_add()
- memblock_reserve()
- memblock_remove()
- memblock_free()
- memblock_alloc()

Introducing test coverage for:
- memblock_alloc_raw()
- memblock_alloc_try_nid_raw()
- memblock_set_bottom_up()
- memblock_bottom_up()
- memblock_trim_memory()

The tests for the memblock_alloc_*raw() functions test both top-down and
bottom-up allocation directions. To add coverage for memblock_alloc_raw(),
the alloc_api was updated so that it runs through all the existing tests
twice: once for memblock_alloc() and once for memblock_alloc_raw(). When
the tests run memblock_alloc_raw(), they test that the entire memory
region is nonzero instead of testing that it is zero.

Similarly, the alloc_nid_api was updated to run through its tests twice:
once for memblock_alloc_try_nid() and once for
memblock_alloc_try_nid_raw(). When the tests run
memblock_alloc_try_nid_raw(), they test that the entire memory region is
nonzero instead of testing that it is zero.

The patch set also adds labels to verbose output for generic
memblock_alloc*() tests that indicate which allocation direction is set.
The function names of those tests do not include this information.

---
Changelog

v1 -> v2
Updates based on feedback from Shaoqin Huang:
PATCH 1:
- tests/alloc_api.c:
- Remove fill_memblock() from alloc_no_memory_generic_check().
- tests/common.c, tests/common.h:
- Change fill_memblock() to file static.
PATCH 3:
- Shaoqin Huang and I discussed using run_top_down() and run_bottom_up()
even for functions with `top_down` and `bottom_up` in the name to
maintain a consistent output style. However, this would make the
output more redundant, so no changes were made.
PATCH 4:
- tests/basic_api.c:
- Rename instances of r1_size and r2_size to
new_r1_size and new_r2_size.
PATCH 6:
- tests/alloc_api.c, tests/alloc_nid_api.c, tests/common.h:
- Change verify_mem_content() to a common function defined in
common.h.
PATCH 8:
- tests/basic_api.c:
- Rename instances of r2_base and r2_size to
new_r2_base and new_r2_size.
---

Rebecca Mckeever (8):
memblock tests: update tests to check if memblock_alloc zeroed memory
memblock tests: update zeroed memory check for memblock_alloc_* tests
memblock tests: add labels to verbose output for generic alloc tests
memblock tests: add additional tests for basic api and memblock_alloc
memblock tests: update alloc_api to test memblock_alloc_raw
memblock tests: update alloc_nid_api to test
memblock_alloc_try_nid_raw
memblock tests: add tests for memblock_*bottom_up functions
memblock tests: add tests for memblock_trim_memory

tools/testing/memblock/tests/alloc_api.c | 175 +++-
.../memblock/tests/alloc_helpers_api.c | 20 +-
tools/testing/memblock/tests/alloc_nid_api.c | 260 +++---
tools/testing/memblock/tests/basic_api.c | 767 ++++++++++++++++++
tools/testing/memblock/tests/common.c | 7 +
tools/testing/memblock/tests/common.h | 53 ++
6 files changed, 1095 insertions(+), 187 deletions(-)

--
2.25.1


2022-08-19 08:57:38

by Rebecca Mckeever

[permalink] [raw]
Subject: [PATCH v2 7/8] memblock tests: add tests for memblock_*bottom_up functions

Add simple tests for memblock_set_bottom_up() and memblock_bottom_up().

Reviewed-by: David Hildenbrand <[email protected]>
Reviewed-by: Shaoqin Huang <[email protected]>
Signed-off-by: Rebecca Mckeever <[email protected]>
---
tools/testing/memblock/tests/basic_api.c | 45 ++++++++++++++++++++++++
1 file changed, 45 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index ea79396e4611..c7490291c485 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -1679,6 +1679,50 @@ static int memblock_free_checks(void)
return 0;
}

+static int memblock_set_bottom_up_check(void)
+{
+ prefix_push("memblock_set_bottom_up");
+
+ memblock_set_bottom_up(false);
+ ASSERT_EQ(memblock.bottom_up, false);
+ memblock_set_bottom_up(true);
+ ASSERT_EQ(memblock.bottom_up, true);
+
+ reset_memblock_attributes();
+ test_pass_pop();
+
+ return 0;
+}
+
+static int memblock_bottom_up_check(void)
+{
+ prefix_push("memblock_bottom_up");
+
+ memblock_set_bottom_up(false);
+ ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);
+ ASSERT_EQ(memblock_bottom_up(), false);
+ memblock_set_bottom_up(true);
+ ASSERT_EQ(memblock_bottom_up(), memblock.bottom_up);
+ ASSERT_EQ(memblock_bottom_up(), true);
+
+ reset_memblock_attributes();
+ test_pass_pop();
+
+ return 0;
+}
+
+static int memblock_bottom_up_checks(void)
+{
+ test_print("Running memblock_*bottom_up tests...\n");
+
+ prefix_reset();
+ memblock_set_bottom_up_check();
+ prefix_reset();
+ memblock_bottom_up_check();
+
+ return 0;
+}
+
int memblock_basic_checks(void)
{
memblock_initialization_check();
@@ -1686,6 +1730,7 @@ int memblock_basic_checks(void)
memblock_reserve_checks();
memblock_remove_checks();
memblock_free_checks();
+ memblock_bottom_up_checks();

return 0;
}
--
2.25.1

2022-08-19 09:32:44

by Rebecca Mckeever

[permalink] [raw]
Subject: [PATCH v2 6/8] memblock tests: update alloc_nid_api to test memblock_alloc_try_nid_raw

Update memblock_alloc_try_nid() tests so that they test either
memblock_alloc_try_nid() or memblock_alloc_try_nid_raw() depending on the
value of alloc_nid_test_flags. Run through all the existing tests in
alloc_nid_api twice: once for memblock_alloc_try_nid() and once for
memblock_alloc_try_nid_raw().

When the tests run memblock_alloc_try_nid(), they test that the entire
memory region is zero. When the tests run memblock_alloc_try_nid_raw(),
they test that the entire memory region is nonzero.

Signed-off-by: Rebecca Mckeever <[email protected]>
---
tools/testing/memblock/tests/alloc_nid_api.c | 188 ++++++++++++-------
1 file changed, 119 insertions(+), 69 deletions(-)

diff --git a/tools/testing/memblock/tests/alloc_nid_api.c b/tools/testing/memblock/tests/alloc_nid_api.c
index 82fa8ea36320..2c1d5035e057 100644
--- a/tools/testing/memblock/tests/alloc_nid_api.c
+++ b/tools/testing/memblock/tests/alloc_nid_api.c
@@ -1,6 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "alloc_nid_api.h"

+static const char * const func_testing[] = {
+ "memblock_alloc_try_nid",
+ "memblock_alloc_try_nid_raw"
+};
+
+static int alloc_nid_test_flags = TEST_ZEROED;
+
+static inline const char * const get_func_testing(int flags)
+{
+ if (flags & TEST_RAW)
+ return func_testing[1];
+ else
+ return func_testing[0];
+}
+
+static inline void *run_memblock_alloc_try_nid(phys_addr_t size,
+ phys_addr_t align,
+ phys_addr_t min_addr,
+ phys_addr_t max_addr, int nid)
+{
+ if (alloc_nid_test_flags & TEST_RAW)
+ return memblock_alloc_try_nid_raw(size, align, min_addr,
+ max_addr, nid);
+ else
+ return memblock_alloc_try_nid(size, align, min_addr,
+ max_addr, nid);
+}
+
/*
* A simple test that tries to allocate a memory region within min_addr and
* max_addr range:
@@ -32,12 +60,13 @@ static int alloc_try_nid_top_down_simple_check(void)
min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2;
max_addr = min_addr + SZ_512;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);
rgn_end = rgn->base + rgn->size;

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, max_addr - size);
@@ -86,12 +115,13 @@ static int alloc_try_nid_top_down_end_misaligned_check(void)
min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2;
max_addr = min_addr + SZ_512 + misalign;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);
rgn_end = rgn->base + rgn->size;

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, max_addr - size - misalign);
@@ -137,12 +167,13 @@ static int alloc_try_nid_exact_address_generic_check(void)
min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES;
max_addr = min_addr + size;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);
rgn_end = rgn->base + rgn->size;

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr);
@@ -189,11 +220,12 @@ static int alloc_try_nid_top_down_narrow_range_check(void)
min_addr = memblock_start_of_DRAM() + SZ_512;
max_addr = min_addr + SMP_CACHE_BYTES;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, max_addr - size);
@@ -241,8 +273,9 @@ static int alloc_try_nid_low_max_generic_check(void)
min_addr = memblock_start_of_DRAM();
max_addr = min_addr + SMP_CACHE_BYTES;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_EQ(allocated_ptr, NULL);

@@ -287,11 +320,12 @@ static int alloc_try_nid_min_reserved_generic_check(void)

memblock_reserve(reserved_base, r1_size);

- allocated_ptr = memblock_alloc_try_nid(r2_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r2_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r2_size);
+ verify_mem_content(allocated_ptr, r2_size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, total_size);
ASSERT_EQ(rgn->base, reserved_base);
@@ -338,11 +372,12 @@ static int alloc_try_nid_max_reserved_generic_check(void)

memblock_reserve(max_addr, r1_size);

- allocated_ptr = memblock_alloc_try_nid(r2_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r2_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r2_size);
+ verify_mem_content(allocated_ptr, r2_size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, total_size);
ASSERT_EQ(rgn->base, min_addr);
@@ -402,11 +437,12 @@ static int alloc_try_nid_top_down_reserved_with_space_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r3_size);
+ verify_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags);

ASSERT_EQ(rgn1->size, r1.size + r3_size);
ASSERT_EQ(rgn1->base, max_addr - r3_size);
@@ -466,11 +502,12 @@ static int alloc_try_nid_reserved_full_merge_generic_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r3_size);
+ verify_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, total_size);
ASSERT_EQ(rgn->base, r2.base);
@@ -531,11 +568,12 @@ static int alloc_try_nid_top_down_reserved_no_space_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r3_size);
+ verify_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags);

ASSERT_EQ(rgn1->size, r1.size);
ASSERT_EQ(rgn1->base, r1.base);
@@ -597,8 +635,9 @@ static int alloc_try_nid_reserved_all_generic_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_EQ(allocated_ptr, NULL);

@@ -628,11 +667,12 @@ static int alloc_try_nid_top_down_cap_max_check(void)
min_addr = memblock_end_of_DRAM() - SZ_1K;
max_addr = memblock_end_of_DRAM() + SZ_256;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - size);
@@ -666,11 +706,12 @@ static int alloc_try_nid_top_down_cap_min_check(void)
min_addr = memblock_start_of_DRAM() - SZ_256;
max_addr = memblock_end_of_DRAM();

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr, NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - size);
@@ -714,13 +755,13 @@ static int alloc_try_nid_bottom_up_simple_check(void)
min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2;
max_addr = min_addr + SZ_512;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);
rgn_end = rgn->base + rgn->size;

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr);
@@ -769,13 +810,13 @@ static int alloc_try_nid_bottom_up_start_misaligned_check(void)
min_addr = memblock_start_of_DRAM() + misalign;
max_addr = min_addr + SZ_512;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);
rgn_end = rgn->base + rgn->size;

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr + (SMP_CACHE_BYTES - misalign));
@@ -822,12 +863,12 @@ static int alloc_try_nid_bottom_up_narrow_range_check(void)
min_addr = memblock_start_of_DRAM() + SZ_512;
max_addr = min_addr + SMP_CACHE_BYTES;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
@@ -887,12 +928,12 @@ static int alloc_try_nid_bottom_up_reserved_with_space_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r3_size);
+ verify_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags);

ASSERT_EQ(rgn1->size, r1.size);
ASSERT_EQ(rgn1->base, max_addr);
@@ -959,12 +1000,12 @@ static int alloc_try_nid_bottom_up_reserved_no_space_check(void)
memblock_reserve(r1.base, r1.size);
memblock_reserve(r2.base, r2.size);

- allocated_ptr = memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(r3_size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, r3_size);
+ verify_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags);

ASSERT_EQ(rgn3->size, r3_size);
ASSERT_EQ(rgn3->base, memblock_start_of_DRAM());
@@ -1004,12 +1045,12 @@ static int alloc_try_nid_bottom_up_cap_max_check(void)
min_addr = memblock_start_of_DRAM() + SZ_1K;
max_addr = memblock_end_of_DRAM() + SZ_256;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, min_addr);
@@ -1043,12 +1084,12 @@ static int alloc_try_nid_bottom_up_cap_min_check(void)
min_addr = memblock_start_of_DRAM();
max_addr = memblock_end_of_DRAM() - SZ_256;

- allocated_ptr = memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
- min_addr, max_addr,
- NUMA_NO_NODE);
+ allocated_ptr = run_memblock_alloc_try_nid(size, SMP_CACHE_BYTES,
+ min_addr, max_addr,
+ NUMA_NO_NODE);

ASSERT_NE(allocated_ptr, NULL);
- ASSERT_MEM_EQ((char *)allocated_ptr, 0, size);
+ verify_mem_content(allocated_ptr, size, alloc_nid_test_flags);

ASSERT_EQ(rgn->size, size);
ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
@@ -1193,13 +1234,14 @@ static int alloc_try_nid_low_max_check(void)
return 0;
}

-int memblock_alloc_nid_checks(void)
+static int memblock_alloc_nid_checks_internal(int flags)
{
- const char *func_testing = "memblock_alloc_try_nid";
+ const char *func = get_func_testing(flags);

+ alloc_nid_test_flags = flags;
prefix_reset();
- prefix_push(func_testing);
- test_print("Running %s tests...\n", func_testing);
+ prefix_push(func);
+ test_print("Running %s tests...\n", func);

reset_memblock_attributes();
dummy_physical_memory_init();
@@ -1225,3 +1267,11 @@ int memblock_alloc_nid_checks(void)

return 0;
}
+
+int memblock_alloc_nid_checks(void)
+{
+ memblock_alloc_nid_checks_internal(TEST_ZEROED);
+ memblock_alloc_nid_checks_internal(TEST_RAW);
+
+ return 0;
+}
--
2.25.1

2022-08-19 09:34:13

by Rebecca Mckeever

[permalink] [raw]
Subject: [PATCH v2 8/8] memblock tests: add tests for memblock_trim_memory

Add tests for memblock_trim_memory() for the following scenarios:
- all regions aligned
- one region unalign that is smaller than the alignment
- one region unaligned at the base
- one region unaligned at the end

Signed-off-by: Rebecca Mckeever <[email protected]>
---
tools/testing/memblock/tests/basic_api.c | 223 +++++++++++++++++++++++
1 file changed, 223 insertions(+)

diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c
index c7490291c485..7048319bb096 100644
--- a/tools/testing/memblock/tests/basic_api.c
+++ b/tools/testing/memblock/tests/basic_api.c
@@ -8,6 +8,7 @@
#define FUNC_RESERVE "memblock_reserve"
#define FUNC_REMOVE "memblock_remove"
#define FUNC_FREE "memblock_free"
+#define FUNC_TRIM "memblock_trim_memory"

static int memblock_initialization_check(void)
{
@@ -1723,6 +1724,227 @@ static int memblock_bottom_up_checks(void)
return 0;
}

+/*
+ * A test that tries to trim memory when both ends of the memory region are
+ * aligned. Expect that the memory will not be trimmed. Expect the counter to
+ * not be updated.
+ */
+static int memblock_trim_memory_aligned_check(void)
+{
+ struct memblock_region *rgn;
+ phys_addr_t alignment = SMP_CACHE_BYTES;
+
+ rgn = &memblock.memory.regions[0];
+
+ struct region r = {
+ .base = alignment,
+ .size = alignment * 4
+ };
+
+ PREFIX_PUSH();
+
+ reset_memblock_regions();
+ memblock_add(r.base, r.size);
+ memblock_trim_memory(alignment);
+
+ ASSERT_EQ(rgn->base, r.base);
+ ASSERT_EQ(rgn->size, r.size);
+
+ ASSERT_EQ(memblock.memory.cnt, 1);
+
+ test_pass_pop();
+
+ return 0;
+}
+
+/*
+ * A test that tries to trim memory when there are two available regions, r1 and
+ * r2. Region r1 is aligned on both ends and region r2 is unaligned on one end
+ * and smaller than the alignment:
+ *
+ * alignment
+ * |--------|
+ * | +-----------------+ +------+ |
+ * | | r1 | | r2 | |
+ * +--------+-----------------+--------+------+---+
+ * ^ ^ ^ ^ ^
+ * |________|________|________| |
+ * | Unaligned address
+ * Aligned addresses
+ *
+ * Expect that r1 will not be trimmed and r2 will be removed. Expect the
+ * counter to be updated.
+ */
+static int memblock_trim_memory_too_small_check(void)
+{
+ struct memblock_region *rgn;
+ phys_addr_t alignment = SMP_CACHE_BYTES;
+
+ rgn = &memblock.memory.regions[0];
+
+ struct region r1 = {
+ .base = alignment,
+ .size = alignment * 2
+ };
+ struct region r2 = {
+ .base = alignment * 4,
+ .size = alignment - SZ_2
+ };
+
+ PREFIX_PUSH();
+
+ reset_memblock_regions();
+ memblock_add(r1.base, r1.size);
+ memblock_add(r2.base, r2.size);
+ memblock_trim_memory(alignment);
+
+ ASSERT_EQ(rgn->base, r1.base);
+ ASSERT_EQ(rgn->size, r1.size);
+
+ ASSERT_EQ(memblock.memory.cnt, 1);
+
+ test_pass_pop();
+
+ return 0;
+}
+
+/*
+ * A test that tries to trim memory when there are two available regions, r1 and
+ * r2. Region r1 is aligned on both ends and region r2 is unaligned at the base
+ * and aligned at the end:
+ *
+ * Unaligned address
+ * |
+ * v
+ * | +-----------------+ +---------------+ |
+ * | | r1 | | r2 | |
+ * +--------+-----------------+----------+---------------+---+
+ * ^ ^ ^ ^ ^ ^
+ * |________|________|________|________|________|
+ * |
+ * Aligned addresses
+ *
+ * Expect that r1 will not be trimmed and r2 will be trimmed at the base.
+ * Expect the counter to not be updated.
+ */
+static int memblock_trim_memory_unaligned_base_check(void)
+{
+ struct memblock_region *rgn1, *rgn2;
+ phys_addr_t alignment = SMP_CACHE_BYTES;
+ phys_addr_t offset = SZ_2;
+ phys_addr_t new_r2_base, new_r2_size;
+
+ rgn1 = &memblock.memory.regions[0];
+ rgn2 = &memblock.memory.regions[1];
+
+ struct region r1 = {
+ .base = alignment,
+ .size = alignment * 2
+ };
+ struct region r2 = {
+ .base = alignment * 4 + offset,
+ .size = alignment * 2 - offset
+ };
+
+ PREFIX_PUSH();
+
+ new_r2_base = r2.base + (alignment - offset);
+ new_r2_size = r2.size - (alignment - offset);
+
+ reset_memblock_regions();
+ memblock_add(r1.base, r1.size);
+ memblock_add(r2.base, r2.size);
+ memblock_trim_memory(alignment);
+
+ ASSERT_EQ(rgn1->base, r1.base);
+ ASSERT_EQ(rgn1->size, r1.size);
+
+ ASSERT_EQ(rgn2->base, new_r2_base);
+ ASSERT_EQ(rgn2->size, new_r2_size);
+
+ ASSERT_EQ(memblock.memory.cnt, 2);
+
+ test_pass_pop();
+
+ return 0;
+}
+
+/*
+ * A test that tries to trim memory when there are two available regions, r1 and
+ * r2. Region r1 is aligned on both ends and region r2 is aligned at the base
+ * and unaligned at the end:
+ *
+ * Unaligned address
+ * |
+ * v
+ * | +-----------------+ +---------------+ |
+ * | | r1 | | r2 | |
+ * +--------+-----------------+--------+---------------+---+
+ * ^ ^ ^ ^ ^ ^
+ * |________|________|________|________|________|
+ * |
+ * Aligned addresses
+ *
+ * Expect that r1 will not be trimmed and r2 will be trimmed at the base.
+ * Expect the counter to not be updated.
+ */
+static int memblock_trim_memory_unaligned_end_check(void)
+{
+ struct memblock_region *rgn1, *rgn2;
+ phys_addr_t alignment = SMP_CACHE_BYTES;
+ phys_addr_t offset = SZ_2;
+ phys_addr_t new_r2_size;
+
+ rgn1 = &memblock.memory.regions[0];
+ rgn2 = &memblock.memory.regions[1];
+
+ struct region r1 = {
+ .base = alignment,
+ .size = alignment * 2
+ };
+ struct region r2 = {
+ .base = alignment * 4,
+ .size = alignment * 2 - offset
+ };
+
+ PREFIX_PUSH();
+
+ new_r2_size = r2.size - (alignment - offset);
+
+ reset_memblock_regions();
+ memblock_add(r1.base, r1.size);
+ memblock_add(r2.base, r2.size);
+ memblock_trim_memory(alignment);
+
+ ASSERT_EQ(rgn1->base, r1.base);
+ ASSERT_EQ(rgn1->size, r1.size);
+
+ ASSERT_EQ(rgn2->base, r2.base);
+ ASSERT_EQ(rgn2->size, new_r2_size);
+
+ ASSERT_EQ(memblock.memory.cnt, 2);
+
+ test_pass_pop();
+
+ return 0;
+}
+
+static int memblock_trim_memory_checks(void)
+{
+ prefix_reset();
+ prefix_push(FUNC_TRIM);
+ test_print("Running %s tests...\n", FUNC_TRIM);
+
+ memblock_trim_memory_aligned_check();
+ memblock_trim_memory_too_small_check();
+ memblock_trim_memory_unaligned_base_check();
+ memblock_trim_memory_unaligned_end_check();
+
+ prefix_pop();
+
+ return 0;
+}
+
int memblock_basic_checks(void)
{
memblock_initialization_check();
@@ -1731,6 +1953,7 @@ int memblock_basic_checks(void)
memblock_remove_checks();
memblock_free_checks();
memblock_bottom_up_checks();
+ memblock_trim_memory_checks();

return 0;
}
--
2.25.1

2022-08-23 13:11:35

by David Hildenbrand

[permalink] [raw]
Subject: Re: [PATCH v2 8/8] memblock tests: add tests for memblock_trim_memory

On 19.08.22 10:34, Rebecca Mckeever wrote:
> Add tests for memblock_trim_memory() for the following scenarios:
> - all regions aligned
> - one region unalign that is smaller than the alignment

s/region unalign/unaligned region/

> - one region unaligned at the base
> - one region unaligned at the end

"unaligned region" ?

[...]

>
> +/*
> + * A test that tries to trim memory when both ends of the memory region are
> + * aligned. Expect that the memory will not be trimmed. Expect the counter to
> + * not be updated.
> + */
> +static int memblock_trim_memory_aligned_check(void)
> +{
> + struct memblock_region *rgn;
> + phys_addr_t alignment = SMP_CACHE_BYTES;

Could make that "const" -- same applies to other functions.

> +
> + rgn = &memblock.memory.regions[0];
> +
> + struct region r = {
> + .base = alignment,
> + .size = alignment * 4
> + };
> +

[[[.]

> +static int memblock_trim_memory_checks(void)
> +{
> + prefix_reset();
> + prefix_push(FUNC_TRIM);
> + test_print("Running %s tests...\n", FUNC_TRIM);

Just a note that this could have been

test_print("Running " FUNC_TRIM " tests...\n");

But it's good to keep this consistent for all tests.


Nice test cases!

--
Thanks,

David / dhildenb

2022-08-23 13:12:01

by David Hildenbrand

[permalink] [raw]
Subject: Re: [PATCH v2 6/8] memblock tests: update alloc_nid_api to test memblock_alloc_try_nid_raw

On 19.08.22 10:34, Rebecca Mckeever wrote:
> Update memblock_alloc_try_nid() tests so that they test either
> memblock_alloc_try_nid() or memblock_alloc_try_nid_raw() depending on the
> value of alloc_nid_test_flags. Run through all the existing tests in
> alloc_nid_api twice: once for memblock_alloc_try_nid() and once for
> memblock_alloc_try_nid_raw().
>
> When the tests run memblock_alloc_try_nid(), they test that the entire
> memory region is zero. When the tests run memblock_alloc_try_nid_raw(),
> they test that the entire memory region is nonzero.
>
> Signed-off-by: Rebecca Mckeever <[email protected]>
> ---
> tools/testing/memblock/tests/alloc_nid_api.c | 188 ++++++++++++-------
> 1 file changed, 119 insertions(+), 69 deletions(-)
>
> diff --git a/tools/testing/memblock/tests/alloc_nid_api.c b/tools/testing/memblock/tests/alloc_nid_api.c
> index 82fa8ea36320..2c1d5035e057 100644
> --- a/tools/testing/memblock/tests/alloc_nid_api.c
> +++ b/tools/testing/memblock/tests/alloc_nid_api.c
> @@ -1,6 +1,34 @@
> // SPDX-License-Identifier: GPL-2.0-or-later
> #include "alloc_nid_api.h"
>
> +static const char * const func_testing[] = {
> + "memblock_alloc_try_nid",
> + "memblock_alloc_try_nid_raw"
> +};
> +
> +static int alloc_nid_test_flags = TEST_ZEROED;
> +
> +static inline const char * const get_func_testing(int flags)
> +{
> + if (flags & TEST_RAW)
> + return func_testing[1];
> + else
> + return func_testing[0];
> +}

Same comments as for patch #5. Otherwise looks good.


--
Thanks,

David / dhildenb