Skip to content

Commit 3d31651

Browse files
RichardWeiYangrppt
authored andcommitted
memblock tests: add memblock_reserve_all_locations_check()
Instead of adding 129th memory block at the last position, let's try all possible position. Signed-off-by: Wei Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mike Rapoport (IBM) <[email protected]>
1 parent 721f4a6 commit 3d31651

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

tools/testing/memblock/tests/basic_api.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,112 @@ static int memblock_reserve_many_check(void)
982982
return 0;
983983
}
984984

985+
986+
/*
987+
* A test that trying to reserve the 129th memory block at all locations.
988+
* Expect to trigger memblock_double_array() to double the
989+
* memblock.memory.max, find a new valid memory as reserved.regions.
990+
*
991+
* 0 1 2 128
992+
* +-------+ +-------+ +-------+ +-------+
993+
* | 32K | | 32K | | 32K | ... | 32K |
994+
* +-------+-------+-------+-------+-------+ +-------+
995+
* |<-32K->| |<-32K->|
996+
*
997+
*/
998+
/* Keep the gap so these memory region will not be merged. */
999+
#define MEMORY_BASE(idx) (SZ_128K + (MEM_SIZE * 2) * (idx))
1000+
static int memblock_reserve_all_locations_check(void)
1001+
{
1002+
int i, skip;
1003+
void *orig_region;
1004+
struct region r = {
1005+
.base = SZ_16K,
1006+
.size = SZ_16K,
1007+
};
1008+
phys_addr_t new_reserved_regions_size;
1009+
1010+
PREFIX_PUSH();
1011+
1012+
/* Reserve the 129th memory block for all possible positions*/
1013+
for (skip = 0; skip < INIT_MEMBLOCK_REGIONS + 1; skip++) {
1014+
reset_memblock_regions();
1015+
memblock_allow_resize();
1016+
1017+
/* Add a valid memory region used by double_array(). */
1018+
dummy_physical_memory_init();
1019+
memblock_add(dummy_physical_memory_base(), MEM_SIZE);
1020+
1021+
for (i = 0; i < INIT_MEMBLOCK_REGIONS + 1; i++) {
1022+
if (i == skip)
1023+
continue;
1024+
1025+
/* Reserve some fakes memory region to fulfill the memblock. */
1026+
memblock_reserve(MEMORY_BASE(i), MEM_SIZE);
1027+
1028+
if (i < skip) {
1029+
ASSERT_EQ(memblock.reserved.cnt, i + 1);
1030+
ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE);
1031+
} else {
1032+
ASSERT_EQ(memblock.reserved.cnt, i);
1033+
ASSERT_EQ(memblock.reserved.total_size, i * MEM_SIZE);
1034+
}
1035+
}
1036+
1037+
orig_region = memblock.reserved.regions;
1038+
1039+
/* This reserve the 129 memory_region, and makes it double array. */
1040+
memblock_reserve(MEMORY_BASE(skip), MEM_SIZE);
1041+
1042+
/*
1043+
* This is the memory region size used by the doubled reserved.regions,
1044+
* and it has been reserved due to it has been used. The size is used to
1045+
* calculate the total_size that the memblock.reserved have now.
1046+
*/
1047+
new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) *
1048+
sizeof(struct memblock_region));
1049+
/*
1050+
* The double_array() will find a free memory region as the new
1051+
* reserved.regions, and the used memory region will be reserved, so
1052+
* there will be one more region exist in the reserved memblock. And the
1053+
* one more reserved region's size is new_reserved_regions_size.
1054+
*/
1055+
ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2);
1056+
ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
1057+
new_reserved_regions_size);
1058+
ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
1059+
1060+
/*
1061+
* Now memblock_double_array() works fine. Let's check after the
1062+
* double_array(), the memblock_reserve() still works as normal.
1063+
*/
1064+
memblock_reserve(r.base, r.size);
1065+
ASSERT_EQ(memblock.reserved.regions[0].base, r.base);
1066+
ASSERT_EQ(memblock.reserved.regions[0].size, r.size);
1067+
1068+
ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3);
1069+
ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE +
1070+
new_reserved_regions_size +
1071+
r.size);
1072+
ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2);
1073+
1074+
dummy_physical_memory_cleanup();
1075+
1076+
/*
1077+
* The current reserved.regions is occupying a range of memory that
1078+
* allocated from dummy_physical_memory_init(). After free the memory,
1079+
* we must not use it. So restore the origin memory region to make sure
1080+
* the tests can run as normal and not affected by the double array.
1081+
*/
1082+
memblock.reserved.regions = orig_region;
1083+
memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS;
1084+
}
1085+
1086+
test_pass_pop();
1087+
1088+
return 0;
1089+
}
1090+
9851091
static int memblock_reserve_checks(void)
9861092
{
9871093
prefix_reset();
@@ -997,6 +1103,7 @@ static int memblock_reserve_checks(void)
9971103
memblock_reserve_between_check();
9981104
memblock_reserve_near_max_check();
9991105
memblock_reserve_many_check();
1106+
memblock_reserve_all_locations_check();
10001107

10011108
prefix_pop();
10021109

0 commit comments

Comments
 (0)