@@ -454,11 +454,216 @@ static int memblock_reserve_checks(void)
454
454
return 0 ;
455
455
}
456
456
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
+
457
661
int memblock_basic_checks (void )
458
662
{
459
663
memblock_initialization_check ();
460
664
memblock_add_checks ();
461
665
memblock_reserve_checks ();
666
+ memblock_remove_checks ();
462
667
463
668
return 0 ;
464
669
}
0 commit comments