memblock: 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() -----BEGIN PGP SIGNATURE----- iQFMBAABCAA2FiEEeOVYVaWZL5900a/pOQOGJssO/ZEFAmNFRd8YHG1pa2UucmFw b3BvcnRAZ21haWwuY29tAAoJEDkDhibLDv2RD7AH/2aaJqtGakZGPtx1IBULg/AE P3/b0OERUjSCzyU3gH8rZ2zG9AsV6Lq/NKeq7B6zdrTJrLs+IlLaGGnbBoO3sEZn KWJWVQlVTyFdT8bdM0BGAAtQvehE6Km1IEoH5c7ColdcBeZKi98MuXY1BEY0KjgJ 76Z+sWOfC+SKV2Yp8A+7anSmD95jZwU4ogr2rHjAgdXAqPQgyUYNvAeawKLapnpQ XjvfWwsEC54PVCw7S1k83Q1VDQ7Vo/b8SMP9/XphcVpwt/6rq3B2uJosRE91ViSe G8M6moNbYtj4n06nNvRNN5zq9igkbjgONCQnBj2D/r6s3SF8Tb3hcznxzORvdK4= =U6/l -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
49da070062
@ -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.
|
||||
|
@ -1,6 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "alloc_api.h"
|
||||
|
||||
static int alloc_test_flags = TEST_F_NONE;
|
||||
|
||||
static inline const char * const get_memblock_alloc_name(int flags)
|
||||
{
|
||||
if (flags & TEST_F_RAW)
|
||||
return "memblock_alloc_raw";
|
||||
return "memblock_alloc";
|
||||
}
|
||||
|
||||
static inline void *run_memblock_alloc(phys_addr_t size, phys_addr_t align)
|
||||
{
|
||||
if (alloc_test_flags & TEST_F_RAW)
|
||||
return memblock_alloc_raw(size, align);
|
||||
return memblock_alloc(size, align);
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries to allocate a small memory region.
|
||||
* Expect to allocate an aligned region near the end of the available memory.
|
||||
@ -9,19 +25,19 @@ static int alloc_top_down_simple_check(void)
|
||||
{
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t size = SZ_2;
|
||||
phys_addr_t expected_start;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
expected_start = memblock_end_of_DRAM() - SMP_CACHE_BYTES;
|
||||
|
||||
allocated_ptr = memblock_alloc(size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, size);
|
||||
ASSERT_EQ(rgn->base, expected_start);
|
||||
|
||||
@ -58,15 +74,13 @@ static int alloc_top_down_disjoint_check(void)
|
||||
struct memblock_region *rgn2 = &memblock.reserved.regions[0];
|
||||
struct region r1;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r2_size = SZ_16;
|
||||
/* Use custom alignment */
|
||||
phys_addr_t alignment = SMP_CACHE_BYTES * 2;
|
||||
phys_addr_t total_size;
|
||||
phys_addr_t expected_start;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
r1.base = memblock_end_of_DRAM() - SZ_2;
|
||||
@ -77,9 +91,11 @@ static int alloc_top_down_disjoint_check(void)
|
||||
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r2_size, alignment);
|
||||
allocated_ptr = run_memblock_alloc(r2_size, alignment);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn1->size, r1.size);
|
||||
ASSERT_EQ(rgn1->base, r1.base);
|
||||
|
||||
@ -108,9 +124,6 @@ static int alloc_top_down_before_check(void)
|
||||
{
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
/*
|
||||
* The first region ends at the aligned address to test region merging
|
||||
*/
|
||||
@ -118,13 +131,16 @@ static int alloc_top_down_before_check(void)
|
||||
phys_addr_t r2_size = SZ_512;
|
||||
phys_addr_t total_size = r1_size + r2_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
memblock_reserve(memblock_end_of_DRAM() - total_size, r1_size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - total_size);
|
||||
|
||||
@ -152,12 +168,10 @@ static int alloc_top_down_after_check(void)
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
struct region r1;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r2_size = SZ_512;
|
||||
phys_addr_t total_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
/*
|
||||
@ -170,9 +184,11 @@ static int alloc_top_down_after_check(void)
|
||||
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
ASSERT_EQ(rgn->base, r1.base - r2_size);
|
||||
|
||||
@ -201,12 +217,10 @@ static int alloc_top_down_second_fit_check(void)
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
struct region r1, r2;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r3_size = SZ_1K;
|
||||
phys_addr_t total_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
r1.base = memblock_end_of_DRAM() - SZ_512;
|
||||
@ -220,9 +234,11 @@ static int alloc_top_down_second_fit_check(void)
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_reserve(r2.base, r2.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, r2.size + r3_size);
|
||||
ASSERT_EQ(rgn->base, r2.base - r3_size);
|
||||
|
||||
@ -250,9 +266,6 @@ static int alloc_in_between_generic_check(void)
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
struct region r1, r2;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t gap_size = SMP_CACHE_BYTES;
|
||||
phys_addr_t r3_size = SZ_64;
|
||||
/*
|
||||
@ -261,6 +274,7 @@ static int alloc_in_between_generic_check(void)
|
||||
phys_addr_t rgn_size = (MEM_SIZE - (2 * gap_size + r3_size)) / 2;
|
||||
phys_addr_t total_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
r1.size = rgn_size;
|
||||
@ -274,9 +288,11 @@ static int alloc_in_between_generic_check(void)
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_reserve(r2.base, r2.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
ASSERT_EQ(rgn->base, r1.base - r2.size - r3_size);
|
||||
|
||||
@ -304,13 +320,11 @@ static int alloc_in_between_generic_check(void)
|
||||
static int alloc_small_gaps_generic_check(void)
|
||||
{
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t region_size = SZ_1K;
|
||||
phys_addr_t gap_size = SZ_256;
|
||||
phys_addr_t region_end;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
region_end = memblock_start_of_DRAM();
|
||||
@ -320,7 +334,7 @@ static int alloc_small_gaps_generic_check(void)
|
||||
region_end += gap_size + region_size;
|
||||
}
|
||||
|
||||
allocated_ptr = memblock_alloc(region_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(region_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_EQ(allocated_ptr, NULL);
|
||||
|
||||
@ -338,13 +352,12 @@ static int alloc_all_reserved_generic_check(void)
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
setup_memblock();
|
||||
|
||||
/* Simulate full memory */
|
||||
memblock_reserve(memblock_start_of_DRAM(), MEM_SIZE);
|
||||
|
||||
allocated_ptr = memblock_alloc(SZ_256, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(SZ_256, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_EQ(allocated_ptr, NULL);
|
||||
|
||||
@ -369,18 +382,16 @@ static int alloc_all_reserved_generic_check(void)
|
||||
static int alloc_no_space_generic_check(void)
|
||||
{
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
setup_memblock();
|
||||
|
||||
phys_addr_t available_size = SZ_256;
|
||||
phys_addr_t reserved_size = MEM_SIZE - available_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
/* Simulate almost-full memory */
|
||||
memblock_reserve(memblock_start_of_DRAM(), reserved_size);
|
||||
|
||||
allocated_ptr = memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_EQ(allocated_ptr, NULL);
|
||||
|
||||
@ -404,20 +415,20 @@ static int alloc_limited_space_generic_check(void)
|
||||
{
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t available_size = SZ_256;
|
||||
phys_addr_t reserved_size = MEM_SIZE - available_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
/* Simulate almost-full memory */
|
||||
memblock_reserve(memblock_start_of_DRAM(), reserved_size);
|
||||
|
||||
allocated_ptr = memblock_alloc(available_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(available_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, available_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, MEM_SIZE);
|
||||
ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
|
||||
|
||||
@ -443,7 +454,40 @@ static int alloc_no_memory_generic_check(void)
|
||||
|
||||
reset_memblock_regions();
|
||||
|
||||
allocated_ptr = memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_EQ(allocated_ptr, NULL);
|
||||
ASSERT_EQ(rgn->size, 0);
|
||||
ASSERT_EQ(rgn->base, 0);
|
||||
ASSERT_EQ(memblock.reserved.total_size, 0);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test that tries to allocate a region that is larger than the total size of
|
||||
* available memory (memblock.memory):
|
||||
*
|
||||
* +-----------------------------------+
|
||||
* | new |
|
||||
* +-----------------------------------+
|
||||
* | |
|
||||
* | |
|
||||
* +---------------------------------+
|
||||
*
|
||||
* Expect no allocation to happen.
|
||||
*/
|
||||
static int alloc_too_large_generic_check(void)
|
||||
{
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
allocated_ptr = run_memblock_alloc(MEM_SIZE + SZ_2, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_EQ(allocated_ptr, NULL);
|
||||
ASSERT_EQ(rgn->size, 0);
|
||||
@ -466,12 +510,13 @@ static int alloc_bottom_up_simple_check(void)
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
setup_memblock();
|
||||
|
||||
allocated_ptr = memblock_alloc(SZ_2, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(SZ_2, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, SZ_2, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, SZ_2);
|
||||
ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
|
||||
|
||||
@ -506,15 +551,13 @@ static int alloc_bottom_up_disjoint_check(void)
|
||||
struct memblock_region *rgn2 = &memblock.reserved.regions[1];
|
||||
struct region r1;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r2_size = SZ_16;
|
||||
/* Use custom alignment */
|
||||
phys_addr_t alignment = SMP_CACHE_BYTES * 2;
|
||||
phys_addr_t total_size;
|
||||
phys_addr_t expected_start;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
r1.base = memblock_start_of_DRAM() + SZ_2;
|
||||
@ -525,9 +568,10 @@ static int alloc_bottom_up_disjoint_check(void)
|
||||
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r2_size, alignment);
|
||||
allocated_ptr = run_memblock_alloc(r2_size, alignment);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn1->size, r1.size);
|
||||
ASSERT_EQ(rgn1->base, r1.base);
|
||||
@ -557,20 +601,20 @@ static int alloc_bottom_up_before_check(void)
|
||||
{
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r1_size = SZ_512;
|
||||
phys_addr_t r2_size = SZ_128;
|
||||
phys_addr_t total_size = r1_size + r2_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
memblock_reserve(memblock_start_of_DRAM() + r1_size, r2_size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r1_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r1_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r1_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
ASSERT_EQ(rgn->base, memblock_start_of_DRAM());
|
||||
|
||||
@ -597,12 +641,10 @@ static int alloc_bottom_up_after_check(void)
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[0];
|
||||
struct region r1;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r2_size = SZ_512;
|
||||
phys_addr_t total_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
/*
|
||||
@ -615,9 +657,11 @@ static int alloc_bottom_up_after_check(void)
|
||||
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r2_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
ASSERT_EQ(rgn->base, r1.base);
|
||||
|
||||
@ -647,12 +691,10 @@ static int alloc_bottom_up_second_fit_check(void)
|
||||
struct memblock_region *rgn = &memblock.reserved.regions[1];
|
||||
struct region r1, r2;
|
||||
void *allocated_ptr = NULL;
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
phys_addr_t r3_size = SZ_1K;
|
||||
phys_addr_t total_size;
|
||||
|
||||
PREFIX_PUSH();
|
||||
setup_memblock();
|
||||
|
||||
r1.base = memblock_start_of_DRAM();
|
||||
@ -666,9 +708,11 @@ static int alloc_bottom_up_second_fit_check(void)
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_reserve(r2.base, r2.size);
|
||||
|
||||
allocated_ptr = memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES);
|
||||
|
||||
ASSERT_NE(allocated_ptr, NULL);
|
||||
assert_mem_content(allocated_ptr, r3_size, alloc_test_flags);
|
||||
|
||||
ASSERT_EQ(rgn->size, r2.size + r3_size);
|
||||
ASSERT_EQ(rgn->base, r2.base);
|
||||
|
||||
@ -728,10 +772,8 @@ static int alloc_after_check(void)
|
||||
static int alloc_in_between_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_in_between_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_in_between_generic_check();
|
||||
run_top_down(alloc_in_between_generic_check);
|
||||
run_bottom_up(alloc_in_between_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -750,10 +792,8 @@ static int alloc_second_fit_check(void)
|
||||
static int alloc_small_gaps_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_small_gaps_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_small_gaps_generic_check();
|
||||
run_top_down(alloc_small_gaps_generic_check);
|
||||
run_bottom_up(alloc_small_gaps_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -761,10 +801,8 @@ static int alloc_small_gaps_check(void)
|
||||
static int alloc_all_reserved_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_all_reserved_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_all_reserved_generic_check();
|
||||
run_top_down(alloc_all_reserved_generic_check);
|
||||
run_bottom_up(alloc_all_reserved_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -772,10 +810,8 @@ static int alloc_all_reserved_check(void)
|
||||
static int alloc_no_space_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_no_space_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_no_space_generic_check();
|
||||
run_top_down(alloc_no_space_generic_check);
|
||||
run_bottom_up(alloc_no_space_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -783,10 +819,8 @@ static int alloc_no_space_check(void)
|
||||
static int alloc_limited_space_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_limited_space_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_limited_space_generic_check();
|
||||
run_top_down(alloc_limited_space_generic_check);
|
||||
run_bottom_up(alloc_limited_space_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -794,21 +828,29 @@ static int alloc_limited_space_check(void)
|
||||
static int alloc_no_memory_check(void)
|
||||
{
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
memblock_set_bottom_up(false);
|
||||
alloc_no_memory_generic_check();
|
||||
memblock_set_bottom_up(true);
|
||||
alloc_no_memory_generic_check();
|
||||
run_top_down(alloc_no_memory_generic_check);
|
||||
run_bottom_up(alloc_no_memory_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memblock_alloc_checks(void)
|
||||
static int alloc_too_large_check(void)
|
||||
{
|
||||
const char *func_testing = "memblock_alloc";
|
||||
test_print("\tRunning %s...\n", __func__);
|
||||
run_top_down(alloc_too_large_generic_check);
|
||||
run_bottom_up(alloc_too_large_generic_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memblock_alloc_checks_internal(int flags)
|
||||
{
|
||||
const char *func = get_memblock_alloc_name(flags);
|
||||
|
||||
alloc_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();
|
||||
@ -824,6 +866,7 @@ int memblock_alloc_checks(void)
|
||||
alloc_no_space_check();
|
||||
alloc_limited_space_check();
|
||||
alloc_no_memory_check();
|
||||
alloc_too_large_check();
|
||||
|
||||
dummy_physical_memory_cleanup();
|
||||
|
||||
@ -831,3 +874,11 @@ int memblock_alloc_checks(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memblock_alloc_checks(void)
|
||||
{
|
||||
memblock_alloc_checks_internal(TEST_F_NONE);
|
||||
memblock_alloc_checks_internal(TEST_F_RAW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
@ -326,6 +327,102 @@ static int memblock_add_twice_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test that tries to add two memory blocks that don't overlap with one
|
||||
* another and then add a third memory block in the space between the first two:
|
||||
*
|
||||
* | +--------+--------+--------+ |
|
||||
* | | r1 | r3 | r2 | |
|
||||
* +--------+--------+--------+--------+--+
|
||||
*
|
||||
* Expect to merge the three entries into one region that starts at r1.base
|
||||
* and has size of r1.size + r2.size + r3.size. The region counter and total
|
||||
* size of the available memory are updated.
|
||||
*/
|
||||
static int memblock_add_between_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.memory.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_1G,
|
||||
.size = SZ_8K
|
||||
};
|
||||
struct region r2 = {
|
||||
.base = SZ_1G + SZ_16K,
|
||||
.size = SZ_8K
|
||||
};
|
||||
struct region r3 = {
|
||||
.base = SZ_1G + SZ_8K,
|
||||
.size = SZ_8K
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = r1.size + r2.size + r3.size;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_add(r1.base, r1.size);
|
||||
memblock_add(r2.base, r2.size);
|
||||
memblock_add(r3.base, r3.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r1.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.memory.cnt, 1);
|
||||
ASSERT_EQ(memblock.memory.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries to add a memory block r when r extends past
|
||||
* PHYS_ADDR_MAX:
|
||||
*
|
||||
* +--------+
|
||||
* | r |
|
||||
* +--------+
|
||||
* | +----+
|
||||
* | | rgn|
|
||||
* +----------------------------+----+
|
||||
*
|
||||
* Expect to add a memory block of size PHYS_ADDR_MAX - r.base. Expect the
|
||||
* total size of available memory and the counter to be updated.
|
||||
*/
|
||||
static int memblock_add_near_max_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.memory.regions[0];
|
||||
|
||||
struct region r = {
|
||||
.base = PHYS_ADDR_MAX - SZ_1M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = PHYS_ADDR_MAX - r.base;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_add(r.base, r.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.memory.cnt, 1);
|
||||
ASSERT_EQ(memblock.memory.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memblock_add_checks(void)
|
||||
{
|
||||
prefix_reset();
|
||||
@ -339,6 +436,8 @@ static int memblock_add_checks(void)
|
||||
memblock_add_overlap_bottom_check();
|
||||
memblock_add_within_check();
|
||||
memblock_add_twice_check();
|
||||
memblock_add_between_check();
|
||||
memblock_add_near_max_check();
|
||||
|
||||
prefix_pop();
|
||||
|
||||
@ -604,6 +703,102 @@ static int memblock_reserve_twice_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test that tries to mark two memory blocks that don't overlap as reserved
|
||||
* and then reserve a third memory block in the space between the first two:
|
||||
*
|
||||
* | +--------+--------+--------+ |
|
||||
* | | r1 | r3 | r2 | |
|
||||
* +--------+--------+--------+--------+--+
|
||||
*
|
||||
* Expect to merge the three entries into one reserved region that starts at
|
||||
* r1.base and has size of r1.size + r2.size + r3.size. The region counter and
|
||||
* total for memblock.reserved are updated.
|
||||
*/
|
||||
static int memblock_reserve_between_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.reserved.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_1G,
|
||||
.size = SZ_8K
|
||||
};
|
||||
struct region r2 = {
|
||||
.base = SZ_1G + SZ_16K,
|
||||
.size = SZ_8K
|
||||
};
|
||||
struct region r3 = {
|
||||
.base = SZ_1G + SZ_8K,
|
||||
.size = SZ_8K
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = r1.size + r2.size + r3.size;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_reserve(r2.base, r2.size);
|
||||
memblock_reserve(r3.base, r3.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r1.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.reserved.cnt, 1);
|
||||
ASSERT_EQ(memblock.reserved.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries to reserve a memory block r when r extends past
|
||||
* PHYS_ADDR_MAX:
|
||||
*
|
||||
* +--------+
|
||||
* | r |
|
||||
* +--------+
|
||||
* | +----+
|
||||
* | | rgn|
|
||||
* +----------------------------+----+
|
||||
*
|
||||
* Expect to reserve a memory block of size PHYS_ADDR_MAX - r.base. Expect the
|
||||
* total size of reserved memory and the counter to be updated.
|
||||
*/
|
||||
static int memblock_reserve_near_max_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.reserved.regions[0];
|
||||
|
||||
struct region r = {
|
||||
.base = PHYS_ADDR_MAX - SZ_1M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = PHYS_ADDR_MAX - r.base;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_reserve(r.base, r.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.reserved.cnt, 1);
|
||||
ASSERT_EQ(memblock.reserved.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memblock_reserve_checks(void)
|
||||
{
|
||||
prefix_reset();
|
||||
@ -616,6 +811,8 @@ static int memblock_reserve_checks(void)
|
||||
memblock_reserve_overlap_bottom_check();
|
||||
memblock_reserve_within_check();
|
||||
memblock_reserve_twice_check();
|
||||
memblock_reserve_between_check();
|
||||
memblock_reserve_near_max_check();
|
||||
|
||||
prefix_pop();
|
||||
|
||||
@ -887,6 +1084,155 @@ static int memblock_remove_within_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries to remove a region r1 from the array of
|
||||
* available memory regions when r1 is the only available region.
|
||||
* Expect to add a memory block r1 and then remove r1 so that a dummy
|
||||
* region is added. The region counter stays the same, and the total size
|
||||
* is updated.
|
||||
*/
|
||||
static int memblock_remove_only_region_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
|
||||
rgn = &memblock.memory.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_2K,
|
||||
.size = SZ_4K
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_add(r1.base, r1.size);
|
||||
memblock_remove(r1.base, r1.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, 0);
|
||||
ASSERT_EQ(rgn->size, 0);
|
||||
|
||||
ASSERT_EQ(memblock.memory.cnt, 1);
|
||||
ASSERT_EQ(memblock.memory.total_size, 0);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries remove a region r2 from the array of available
|
||||
* memory regions when r2 extends past PHYS_ADDR_MAX:
|
||||
*
|
||||
* +--------+
|
||||
* | r2 |
|
||||
* +--------+
|
||||
* | +---+....+
|
||||
* | |rgn| |
|
||||
* +------------------------+---+----+
|
||||
*
|
||||
* Expect that only the portion between PHYS_ADDR_MAX and r2.base is removed.
|
||||
* Expect the total size of available memory to be updated and the counter to
|
||||
* not be updated.
|
||||
*/
|
||||
static int memblock_remove_near_max_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.memory.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = PHYS_ADDR_MAX - SZ_2M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
struct region r2 = {
|
||||
.base = PHYS_ADDR_MAX - SZ_1M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = r1.size - (PHYS_ADDR_MAX - r2.base);
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_add(r1.base, r1.size);
|
||||
memblock_remove(r2.base, r2.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r1.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.memory.cnt, 1);
|
||||
ASSERT_EQ(memblock.memory.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test that tries to remove a region r3 that overlaps with two existing
|
||||
* regions r1 and r2:
|
||||
*
|
||||
* +----------------+
|
||||
* | r3 |
|
||||
* +----------------+
|
||||
* | +----+..... ........+--------+
|
||||
* | | |r1 : : |r2 | |
|
||||
* +----+----+----+---+-------+--------+-----+
|
||||
*
|
||||
* Expect that only the intersections of r1 with r3 and r2 with r3 are removed
|
||||
* from the available memory pool. Expect the total size of available memory to
|
||||
* be updated and the counter to not be updated.
|
||||
*/
|
||||
static int memblock_remove_overlap_two_check(void)
|
||||
{
|
||||
struct memblock_region *rgn1, *rgn2;
|
||||
phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;
|
||||
|
||||
rgn1 = &memblock.memory.regions[0];
|
||||
rgn2 = &memblock.memory.regions[1];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_16M,
|
||||
.size = SZ_32M
|
||||
};
|
||||
struct region r2 = {
|
||||
.base = SZ_64M,
|
||||
.size = SZ_64M
|
||||
};
|
||||
struct region r3 = {
|
||||
.base = SZ_32M,
|
||||
.size = SZ_64M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
r2_end = r2.base + r2.size;
|
||||
r3_end = r3.base + r3.size;
|
||||
new_r1_size = r3.base - r1.base;
|
||||
new_r2_size = r2_end - r3_end;
|
||||
total_size = new_r1_size + new_r2_size;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_add(r1.base, r1.size);
|
||||
memblock_add(r2.base, r2.size);
|
||||
memblock_remove(r3.base, r3.size);
|
||||
|
||||
ASSERT_EQ(rgn1->base, r1.base);
|
||||
ASSERT_EQ(rgn1->size, new_r1_size);
|
||||
|
||||
ASSERT_EQ(rgn2->base, r3_end);
|
||||
ASSERT_EQ(rgn2->size, new_r2_size);
|
||||
|
||||
ASSERT_EQ(memblock.memory.cnt, 2);
|
||||
ASSERT_EQ(memblock.memory.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memblock_remove_checks(void)
|
||||
{
|
||||
prefix_reset();
|
||||
@ -898,6 +1244,9 @@ static int memblock_remove_checks(void)
|
||||
memblock_remove_overlap_top_check();
|
||||
memblock_remove_overlap_bottom_check();
|
||||
memblock_remove_within_check();
|
||||
memblock_remove_only_region_check();
|
||||
memblock_remove_near_max_check();
|
||||
memblock_remove_overlap_two_check();
|
||||
|
||||
prefix_pop();
|
||||
|
||||
@ -1163,6 +1512,154 @@ static int memblock_free_within_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries to free a memory block r1 that was marked
|
||||
* earlier as reserved when r1 is the only available region.
|
||||
* Expect to reserve a memory block r1 and then free r1 so that r1 is
|
||||
* overwritten with a dummy region. The region counter stays the same,
|
||||
* and the total size is updated.
|
||||
*/
|
||||
static int memblock_free_only_region_check(void)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
|
||||
rgn = &memblock.reserved.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_2K,
|
||||
.size = SZ_4K
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_free((void *)r1.base, r1.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, 0);
|
||||
ASSERT_EQ(rgn->size, 0);
|
||||
|
||||
ASSERT_EQ(memblock.reserved.cnt, 1);
|
||||
ASSERT_EQ(memblock.reserved.total_size, 0);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple test that tries free a region r2 when r2 extends past PHYS_ADDR_MAX:
|
||||
*
|
||||
* +--------+
|
||||
* | r2 |
|
||||
* +--------+
|
||||
* | +---+....+
|
||||
* | |rgn| |
|
||||
* +------------------------+---+----+
|
||||
*
|
||||
* Expect that only the portion between PHYS_ADDR_MAX and r2.base is freed.
|
||||
* 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)
|
||||
{
|
||||
struct memblock_region *rgn;
|
||||
phys_addr_t total_size;
|
||||
|
||||
rgn = &memblock.reserved.regions[0];
|
||||
|
||||
struct region r1 = {
|
||||
.base = PHYS_ADDR_MAX - SZ_2M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
struct region r2 = {
|
||||
.base = PHYS_ADDR_MAX - SZ_1M,
|
||||
.size = SZ_2M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
total_size = r1.size - (PHYS_ADDR_MAX - r2.base);
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_free((void *)r2.base, r2.size);
|
||||
|
||||
ASSERT_EQ(rgn->base, r1.base);
|
||||
ASSERT_EQ(rgn->size, total_size);
|
||||
|
||||
ASSERT_EQ(memblock.reserved.cnt, 1);
|
||||
ASSERT_EQ(memblock.reserved.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A test that tries to free a reserved region r3 that overlaps with two
|
||||
* existing reserved regions r1 and r2:
|
||||
*
|
||||
* +----------------+
|
||||
* | r3 |
|
||||
* +----------------+
|
||||
* | +----+..... ........+--------+
|
||||
* | | |r1 : : |r2 | |
|
||||
* +----+----+----+---+-------+--------+-----+
|
||||
*
|
||||
* Expect that only the intersections of r1 with r3 and r2 with r3 are freed
|
||||
* from the collection of reserved memory. Expect the total size of reserved
|
||||
* memory to be updated and the counter to not be updated.
|
||||
*/
|
||||
static int memblock_free_overlap_two_check(void)
|
||||
{
|
||||
struct memblock_region *rgn1, *rgn2;
|
||||
phys_addr_t new_r1_size, new_r2_size, r2_end, r3_end, total_size;
|
||||
|
||||
rgn1 = &memblock.reserved.regions[0];
|
||||
rgn2 = &memblock.reserved.regions[1];
|
||||
|
||||
struct region r1 = {
|
||||
.base = SZ_16M,
|
||||
.size = SZ_32M
|
||||
};
|
||||
struct region r2 = {
|
||||
.base = SZ_64M,
|
||||
.size = SZ_64M
|
||||
};
|
||||
struct region r3 = {
|
||||
.base = SZ_32M,
|
||||
.size = SZ_64M
|
||||
};
|
||||
|
||||
PREFIX_PUSH();
|
||||
|
||||
r2_end = r2.base + r2.size;
|
||||
r3_end = r3.base + r3.size;
|
||||
new_r1_size = r3.base - r1.base;
|
||||
new_r2_size = r2_end - r3_end;
|
||||
total_size = new_r1_size + new_r2_size;
|
||||
|
||||
reset_memblock_regions();
|
||||
memblock_reserve(r1.base, r1.size);
|
||||
memblock_reserve(r2.base, r2.size);
|
||||
memblock_free((void *)r3.base, r3.size);
|
||||
|
||||
ASSERT_EQ(rgn1->base, r1.base);
|
||||
ASSERT_EQ(rgn1->size, new_r1_size);
|
||||
|
||||
ASSERT_EQ(rgn2->base, r3_end);
|
||||
ASSERT_EQ(rgn2->size, new_r2_size);
|
||||
|
||||
ASSERT_EQ(memblock.reserved.cnt, 2);
|
||||
ASSERT_EQ(memblock.reserved.total_size, total_size);
|
||||
|
||||
test_pass_pop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memblock_free_checks(void)
|
||||
{
|
||||
prefix_reset();
|
||||
@ -1174,6 +1671,274 @@ static int memblock_free_checks(void)
|
||||
memblock_free_overlap_top_check();
|
||||
memblock_free_overlap_bottom_check();
|
||||
memblock_free_within_check();
|
||||
memblock_free_only_region_check();
|
||||
memblock_free_near_max_check();
|
||||
memblock_free_overlap_two_check();
|
||||
|
||||
prefix_pop();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
const 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;
|
||||
const 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;
|
||||
const 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 end.
|
||||
* Expect the counter to not be updated.
|
||||
*/
|
||||
static int memblock_trim_memory_unaligned_end_check(void)
|
||||
{
|
||||
struct memblock_region *rgn1, *rgn2;
|
||||
const 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();
|
||||
|
||||
@ -1187,6 +1952,8 @@ int memblock_basic_checks(void)
|
||||
memblock_reserve_checks();
|
||||
memblock_remove_checks();
|
||||
memblock_free_checks();
|
||||
memblock_bottom_up_checks();
|
||||
memblock_trim_memory_checks();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user