Skip to content

Commit b4d9689

Browse files
drobnikrppt
authored andcommitted
memblock tests: Add memblock_remove tests
Add checks for removing a region from available memory in different scenarios: - The requested region matches one in the collection of available memory regions - The requested region does not exist in memblock.memory - The region overlaps with one of the entries: from the top (its end address is bigger than the base of the existing region) or from the bottom (its base address is smaller than the end address of one of the regions) - The region is within an already defined region Signed-off-by: Karolina Drobnik <[email protected]> Signed-off-by: Mike Rapoport <[email protected]> Link: https://lore.kernel.org/r/8e6aa005407bbe1a75b75e85ac04ebb51318a52a.1643796665.git.karolinadrobnik@gmail.com
1 parent 83787a8 commit b4d9689

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

tools/testing/memblock/tests/basic_api.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,216 @@ static int memblock_reserve_checks(void)
454454
return 0;
455455
}
456456

457+
/*
458+
* A simple test that tries to remove the first entry of the array of
459+
* available memory regions. By "removing" a region we mean overwriting it
460+
* with the next region in memblock.memory. To check this is the case, the
461+
* test adds two memory blocks and verifies that the value of the latter
462+
* was used to erase r1 region. It also checks if the region counter and
463+
* total size were updated to expected values.
464+
*/
465+
static int memblock_remove_simple_check(void)
466+
{
467+
struct memblock_region *rgn;
468+
469+
rgn = &memblock.memory.regions[0];
470+
471+
struct region r1 = {
472+
.base = SZ_2K,
473+
.size = SZ_4K
474+
};
475+
struct region r2 = {
476+
.base = SZ_128K,
477+
.size = SZ_4M
478+
};
479+
480+
reset_memblock();
481+
memblock_add(r1.base, r1.size);
482+
memblock_add(r2.base, r2.size);
483+
memblock_remove(r1.base, r1.size);
484+
485+
assert(rgn->base == r2.base);
486+
assert(rgn->size == r2.size);
487+
488+
assert(memblock.memory.cnt == 1);
489+
assert(memblock.memory.total_size == r2.size);
490+
491+
return 0;
492+
}
493+
494+
/*
495+
* A test that tries to remove a region that was not registered as available
496+
* memory (i.e. has no corresponding entry in memblock.memory). It verifies
497+
* that array, regions counter and total size were not modified.
498+
*/
499+
static int memblock_remove_absent_check(void)
500+
{
501+
struct memblock_region *rgn;
502+
503+
rgn = &memblock.memory.regions[0];
504+
505+
struct region r1 = {
506+
.base = SZ_512K,
507+
.size = SZ_4M
508+
};
509+
struct region r2 = {
510+
.base = SZ_64M,
511+
.size = SZ_1G
512+
};
513+
514+
reset_memblock();
515+
memblock_add(r1.base, r1.size);
516+
memblock_remove(r2.base, r2.size);
517+
518+
assert(rgn->base == r1.base);
519+
assert(rgn->size == r1.size);
520+
521+
assert(memblock.memory.cnt == 1);
522+
assert(memblock.memory.total_size == r1.size);
523+
524+
return 0;
525+
}
526+
527+
/*
528+
* A test that tries to remove a region which overlaps with the beginning of
529+
* the already existing entry r1 (that is r1.base < r2.base + r2.size). It
530+
* checks if only the intersection of both regions is removed from the available
531+
* memory pool. The test also checks if the regions counter and total size are
532+
* updated to expected values.
533+
*/
534+
static int memblock_remove_overlap_top_check(void)
535+
{
536+
struct memblock_region *rgn;
537+
phys_addr_t r1_end, r2_end, total_size;
538+
539+
rgn = &memblock.memory.regions[0];
540+
541+
struct region r1 = {
542+
.base = SZ_32M,
543+
.size = SZ_32M
544+
};
545+
struct region r2 = {
546+
.base = SZ_16M,
547+
.size = SZ_32M
548+
};
549+
550+
r1_end = r1.base + r1.size;
551+
r2_end = r2.base + r2.size;
552+
total_size = r1_end - r2_end;
553+
554+
reset_memblock();
555+
memblock_add(r1.base, r1.size);
556+
memblock_remove(r2.base, r2.size);
557+
558+
assert(rgn->base == r1.base + r2.base);
559+
assert(rgn->size == total_size);
560+
561+
assert(memblock.memory.cnt == 1);
562+
assert(memblock.memory.total_size == total_size);
563+
564+
return 0;
565+
}
566+
567+
/*
568+
* A test that tries to remove a region which overlaps with the end of the
569+
* first entry (that is r2.base < r1.base + r1.size). It checks if only the
570+
* intersection of both regions is removed from the available memory pool.
571+
* The test also checks if the regions counter and total size are updated to
572+
* expected values.
573+
*/
574+
static int memblock_remove_overlap_bottom_check(void)
575+
{
576+
struct memblock_region *rgn;
577+
phys_addr_t total_size;
578+
579+
rgn = &memblock.memory.regions[0];
580+
581+
struct region r1 = {
582+
.base = SZ_2M,
583+
.size = SZ_64M
584+
};
585+
struct region r2 = {
586+
.base = SZ_32M,
587+
.size = SZ_256M
588+
};
589+
590+
total_size = r2.base - r1.base;
591+
592+
reset_memblock();
593+
memblock_add(r1.base, r1.size);
594+
memblock_remove(r2.base, r2.size);
595+
596+
assert(rgn->base == r1.base);
597+
assert(rgn->size == total_size);
598+
599+
assert(memblock.memory.cnt == 1);
600+
assert(memblock.memory.total_size == total_size);
601+
return 0;
602+
}
603+
604+
/*
605+
* A test that tries to remove a region which is within the range of the
606+
* already existing entry (that is
607+
* (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
608+
* It checks if the region is split into two - one that ends at r2.base and
609+
* second that starts at r2.base + size, with appropriate sizes. The test
610+
* also checks if the region counter and total size were updated to
611+
* expected values.
612+
*/
613+
static int memblock_remove_within_check(void)
614+
{
615+
struct memblock_region *rgn1, *rgn2;
616+
phys_addr_t r1_size, r2_size, total_size;
617+
618+
rgn1 = &memblock.memory.regions[0];
619+
rgn2 = &memblock.memory.regions[1];
620+
621+
struct region r1 = {
622+
.base = SZ_1M,
623+
.size = SZ_32M
624+
};
625+
struct region r2 = {
626+
.base = SZ_16M,
627+
.size = SZ_1M
628+
};
629+
630+
r1_size = r2.base - r1.base;
631+
r2_size = (r1.base + r1.size) - (r2.base + r2.size);
632+
total_size = r1_size + r2_size;
633+
634+
reset_memblock();
635+
memblock_add(r1.base, r1.size);
636+
memblock_remove(r2.base, r2.size);
637+
638+
assert(rgn1->base == r1.base);
639+
assert(rgn1->size == r1_size);
640+
641+
assert(rgn2->base == r2.base + r2.size);
642+
assert(rgn2->size == r2_size);
643+
644+
assert(memblock.memory.cnt == 2);
645+
assert(memblock.memory.total_size == total_size);
646+
647+
return 0;
648+
}
649+
650+
static int memblock_remove_checks(void)
651+
{
652+
memblock_remove_simple_check();
653+
memblock_remove_absent_check();
654+
memblock_remove_overlap_top_check();
655+
memblock_remove_overlap_bottom_check();
656+
memblock_remove_within_check();
657+
658+
return 0;
659+
}
660+
457661
int memblock_basic_checks(void)
458662
{
459663
memblock_initialization_check();
460664
memblock_add_checks();
461665
memblock_reserve_checks();
666+
memblock_remove_checks();
462667

463668
return 0;
464669
}

0 commit comments

Comments
 (0)