On Sun, Apr 14, 2024 at 12:45:27AM +0000, Wei Yang wrote: > After previous change, we may double the array based on the position of > the new range. > > Let's make sure the 129th memory block would double the size correctly > at all possible position. Rather than rewrite an existing test, just add a new one. Besides, it would be more interesting to test additions to memblock.reserved and a mix of memblock_add() and memblock_reserve() that will require resizing the memblock arrays. > Signed-off-by: Wei Yang <richard.weiyang@xxxxxxxxx> > --- > tools/testing/memblock/tests/basic_api.c | 132 +++++++++++++---------- > 1 file changed, 73 insertions(+), 59 deletions(-) > > diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c > index f317fe691fc4..f1569ebb9872 100644 > --- a/tools/testing/memblock/tests/basic_api.c > +++ b/tools/testing/memblock/tests/basic_api.c > @@ -431,84 +431,98 @@ static int memblock_add_near_max_check(void) > */ > static int memblock_add_many_check(void) > { > - int i; > + int i, skip; > void *orig_region; > struct region r = { > .base = SZ_16K, > .size = SZ_16K, > }; > phys_addr_t new_memory_regions_size; > - phys_addr_t base, size = SZ_64; > + phys_addr_t base, base_start, size = SZ_64; > phys_addr_t gap_size = SZ_64; > > PREFIX_PUSH(); > > - reset_memblock_regions(); > - memblock_allow_resize(); > - > - dummy_physical_memory_init(); > - /* > - * We allocated enough memory by using dummy_physical_memory_init(), and > - * split it into small block. First we split a large enough memory block > - * as the memory region which will be choosed by memblock_double_array(). > - */ > - base = PAGE_ALIGN(dummy_physical_memory_base()); > - new_memory_regions_size = PAGE_ALIGN(INIT_MEMBLOCK_REGIONS * 2 * > - sizeof(struct memblock_region)); > - memblock_add(base, new_memory_regions_size); > - > - /* This is the base of small memory block. */ > - base += new_memory_regions_size + gap_size; > - > - orig_region = memblock.memory.regions; > + /* Add the 129th memory block for all possible positions*/ > + for (skip = 0; skip < INIT_MEMBLOCK_REGIONS; skip++) { > + reset_memblock_regions(); > + memblock_allow_resize(); > > - for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) { > + dummy_physical_memory_init(); > /* > - * Add these small block to fulfill the memblock. We keep a > - * gap between the nearby memory to avoid being merged. > + * We allocated enough memory by using dummy_physical_memory_init(), and > + * split it into small block. First we split a large enough memory block > + * as the memory region which will be choosed by memblock_double_array(). > */ > - memblock_add(base, size); > - base += size + gap_size; > - > - ASSERT_EQ(memblock.memory.cnt, i + 2); > + base = PAGE_ALIGN(dummy_physical_memory_base()); > + new_memory_regions_size = PAGE_ALIGN(INIT_MEMBLOCK_REGIONS * 2 * > + sizeof(struct memblock_region)); > + memblock_add(base, new_memory_regions_size); > + > + /* This is the base of small memory block. */ > + base_start = base += new_memory_regions_size + gap_size; > + orig_region = memblock.memory.regions; > + > + for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++, base += size + gap_size) { > + if (i == skip) > + continue; > + /* > + * Add these small block to fulfill the memblock. We keep a > + * gap between the nearby memory to avoid being merged. > + */ > + memblock_add(base, size); > + > + if (i < skip) { > + ASSERT_EQ(memblock.memory.cnt, i + 2); > + ASSERT_EQ(memblock.memory.total_size, > + new_memory_regions_size + (i + 1) * size); > + } else { > + ASSERT_EQ(memblock.memory.cnt, i + 1); > + ASSERT_EQ(memblock.memory.total_size, > + new_memory_regions_size + i * size); > + } > + } > + > + /* Add the skipped one to trigger memblock_double_array() */ > + memblock_add(base_start + skip * (size + gap_size), size); > + ASSERT_EQ(memblock.memory.cnt, i + 1); > ASSERT_EQ(memblock.memory.total_size, new_memory_regions_size + > - (i + 1) * size); > - } > + i * size); > + /* > + * At there, memblock_double_array() has been succeed, check if it > + * update the memory.max. > + */ > + ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2); > > - /* > - * At there, memblock_double_array() has been succeed, check if it > - * update the memory.max. > - */ > - ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2); > + /* memblock_double_array() will reserve the memory it used. Check it. */ > + ASSERT_EQ(memblock.reserved.cnt, 1); > + ASSERT_EQ(memblock.reserved.total_size, new_memory_regions_size); > > - /* memblock_double_array() will reserve the memory it used. Check it. */ > - ASSERT_EQ(memblock.reserved.cnt, 1); > - ASSERT_EQ(memblock.reserved.total_size, new_memory_regions_size); > - > - /* > - * Now memblock_double_array() works fine. Let's check after the > - * double_array(), the memblock_add() still works as normal. > - */ > - memblock_add(r.base, r.size); > - ASSERT_EQ(memblock.memory.regions[0].base, r.base); > - ASSERT_EQ(memblock.memory.regions[0].size, r.size); > + /* > + * Now memblock_double_array() works fine. Let's check after the > + * double_array(), the memblock_add() still works as normal. > + */ > + memblock_add(r.base, r.size); > + ASSERT_EQ(memblock.memory.regions[0].base, r.base); > + ASSERT_EQ(memblock.memory.regions[0].size, r.size); > > - ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 2); > - ASSERT_EQ(memblock.memory.total_size, INIT_MEMBLOCK_REGIONS * size + > - new_memory_regions_size + > - r.size); > - ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2); > + ASSERT_EQ(memblock.memory.cnt, INIT_MEMBLOCK_REGIONS + 2); > + ASSERT_EQ(memblock.memory.total_size, INIT_MEMBLOCK_REGIONS * size + > + new_memory_regions_size + > + r.size); > + ASSERT_EQ(memblock.memory.max, INIT_MEMBLOCK_REGIONS * 2); > > - dummy_physical_memory_cleanup(); > + dummy_physical_memory_cleanup(); > > - /* > - * The current memory.regions is occupying a range of memory that > - * allocated from dummy_physical_memory_init(). After free the memory, > - * we must not use it. So restore the origin memory region to make sure > - * the tests can run as normal and not affected by the double array. > - */ > - memblock.memory.regions = orig_region; > - memblock.memory.cnt = INIT_MEMBLOCK_REGIONS; > + /* > + * The current memory.regions is occupying a range of memory that > + * allocated from dummy_physical_memory_init(). After free the memory, > + * we must not use it. So restore the origin memory region to make sure > + * the tests can run as normal and not affected by the double array. > + */ > + memblock.memory.regions = orig_region; > + memblock.memory.cnt = INIT_MEMBLOCK_REGIONS; > + } > > test_pass_pop(); > > -- > 2.34.1 > -- Sincerely yours, Mike.