@@ -411,23 +411,339 @@ static int alloc_no_memory_generic_check(void)
411
411
return 0 ;
412
412
}
413
413
414
- int memblock_alloc_checks (void )
414
+ /*
415
+ * A simple test that tries to allocate a small memory region.
416
+ * Expect to allocate an aligned region at the beginning of the available
417
+ * memory.
418
+ */
419
+ static int alloc_bottom_up_simple_check (void )
415
420
{
416
- reset_memblock_attributes ();
417
- dummy_physical_memory_init ();
421
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
422
+ void * allocated_ptr = NULL ;
423
+
424
+ setup_memblock ();
425
+
426
+ allocated_ptr = memblock_alloc (SZ_2 , SMP_CACHE_BYTES );
427
+
428
+ assert (allocated_ptr );
429
+ assert (rgn -> size == SZ_2 );
430
+ assert (rgn -> base == memblock_start_of_DRAM ());
431
+
432
+ assert (memblock .reserved .cnt == 1 );
433
+ assert (memblock .reserved .total_size == SZ_2 );
434
+
435
+ return 0 ;
436
+ }
437
+
438
+ /*
439
+ * A test that tries to allocate memory next to a reserved region that starts at
440
+ * the misaligned address. Expect to create two separate entries, with the new
441
+ * entry aligned to the provided alignment:
442
+ *
443
+ * +
444
+ * | +----------+ +----------+ |
445
+ * | | rgn1 | | rgn2 | |
446
+ * +----+----------+---+----------+-----+
447
+ * ^
448
+ * |
449
+ * Aligned address boundary
450
+ *
451
+ * The allocation direction is bottom-up, so the new region will be the second
452
+ * entry in memory.reserved array. The previously reserved region does not get
453
+ * modified. Region counter and total size get updated.
454
+ */
455
+ static int alloc_bottom_up_disjoint_check (void )
456
+ {
457
+ struct memblock_region * rgn1 = & memblock .reserved .regions [0 ];
458
+ struct memblock_region * rgn2 = & memblock .reserved .regions [1 ];
459
+ struct region r1 ;
460
+ void * allocated_ptr = NULL ;
461
+
462
+ phys_addr_t r2_size = SZ_16 ;
463
+ /* Use custom alignment */
464
+ phys_addr_t alignment = SMP_CACHE_BYTES * 2 ;
465
+ phys_addr_t total_size ;
466
+ phys_addr_t expected_start ;
467
+
468
+ setup_memblock ();
469
+
470
+ r1 .base = memblock_start_of_DRAM () + SZ_2 ;
471
+ r1 .size = SZ_2 ;
472
+
473
+ total_size = r1 .size + r2_size ;
474
+ expected_start = memblock_start_of_DRAM () + alignment ;
418
475
476
+ memblock_reserve (r1 .base , r1 .size );
477
+
478
+ allocated_ptr = memblock_alloc (r2_size , alignment );
479
+
480
+ assert (allocated_ptr );
481
+
482
+ assert (rgn1 -> size == r1 .size );
483
+ assert (rgn1 -> base == r1 .base );
484
+
485
+ assert (rgn2 -> size == r2_size );
486
+ assert (rgn2 -> base == expected_start );
487
+
488
+ assert (memblock .reserved .cnt == 2 );
489
+ assert (memblock .reserved .total_size == total_size );
490
+
491
+ return 0 ;
492
+ }
493
+
494
+ /*
495
+ * A test that tries to allocate memory when there is enough space at
496
+ * the beginning of the previously reserved block (i.e. first fit):
497
+ *
498
+ * |------------------+--------+ |
499
+ * | r1 | r2 | |
500
+ * +------------------+--------+---------+
501
+ *
502
+ * Expect a merge of both regions. Only the region size gets updated.
503
+ */
504
+ static int alloc_bottom_up_before_check (void )
505
+ {
506
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
507
+ void * allocated_ptr = NULL ;
508
+
509
+ phys_addr_t r1_size = SZ_512 ;
510
+ phys_addr_t r2_size = SZ_128 ;
511
+ phys_addr_t total_size = r1_size + r2_size ;
512
+
513
+ setup_memblock ();
514
+
515
+ memblock_reserve (memblock_start_of_DRAM () + r1_size , r2_size );
516
+
517
+ allocated_ptr = memblock_alloc (r1_size , SMP_CACHE_BYTES );
518
+
519
+ assert (allocated_ptr );
520
+ assert (rgn -> size == total_size );
521
+ assert (rgn -> base == memblock_start_of_DRAM ());
522
+
523
+ assert (memblock .reserved .cnt == 1 );
524
+ assert (memblock .reserved .total_size == total_size );
525
+
526
+ return 0 ;
527
+ }
528
+
529
+ /*
530
+ * A test that tries to allocate memory when there is not enough space at
531
+ * the beginning of the previously reserved block (i.e. second fit):
532
+ *
533
+ * | +--------+--------------+ |
534
+ * | | r1 | r2 | |
535
+ * +----+--------+--------------+---------+
536
+ *
537
+ * Expect a merge of both regions. Only the region size gets updated.
538
+ */
539
+ static int alloc_bottom_up_after_check (void )
540
+ {
541
+ struct memblock_region * rgn = & memblock .reserved .regions [0 ];
542
+ struct region r1 ;
543
+ void * allocated_ptr = NULL ;
544
+
545
+ phys_addr_t r2_size = SZ_512 ;
546
+ phys_addr_t total_size ;
547
+
548
+ setup_memblock ();
549
+
550
+ /*
551
+ * The first region starts at the aligned address to test region merging
552
+ */
553
+ r1 .base = memblock_start_of_DRAM () + SMP_CACHE_BYTES ;
554
+ r1 .size = SZ_64 ;
555
+
556
+ total_size = r1 .size + r2_size ;
557
+
558
+ memblock_reserve (r1 .base , r1 .size );
559
+
560
+ allocated_ptr = memblock_alloc (r2_size , SMP_CACHE_BYTES );
561
+
562
+ assert (allocated_ptr );
563
+ assert (rgn -> size == total_size );
564
+ assert (rgn -> base == r1 .base );
565
+
566
+ assert (memblock .reserved .cnt == 1 );
567
+ assert (memblock .reserved .total_size == total_size );
568
+
569
+ return 0 ;
570
+ }
571
+
572
+ /*
573
+ * A test that tries to allocate memory when there are two reserved regions, the
574
+ * first one starting at the beginning of the available memory, with a gap too
575
+ * small to fit the new region:
576
+ *
577
+ * |------------+ +--------+--------+ |
578
+ * | r1 | | r2 | r3 | |
579
+ * +------------+-----+--------+--------+--+
580
+ *
581
+ * Expect to allocate after the second region, which starts at the higher
582
+ * address, and merge them into one. The region counter and total size fields
583
+ * get updated.
584
+ */
585
+ static int alloc_bottom_up_second_fit_check (void )
586
+ {
587
+ struct memblock_region * rgn = & memblock .reserved .regions [1 ];
588
+ struct region r1 , r2 ;
589
+ void * allocated_ptr = NULL ;
590
+
591
+ phys_addr_t r3_size = SZ_1K ;
592
+ phys_addr_t total_size ;
593
+
594
+ setup_memblock ();
595
+
596
+ r1 .base = memblock_start_of_DRAM ();
597
+ r1 .size = SZ_512 ;
598
+
599
+ r2 .base = r1 .base + r1 .size + SZ_512 ;
600
+ r2 .size = SZ_256 ;
601
+
602
+ total_size = r1 .size + r2 .size + r3_size ;
603
+
604
+ memblock_reserve (r1 .base , r1 .size );
605
+ memblock_reserve (r2 .base , r2 .size );
606
+
607
+ allocated_ptr = memblock_alloc (r3_size , SMP_CACHE_BYTES );
608
+
609
+ assert (allocated_ptr );
610
+ assert (rgn -> size == r2 .size + r3_size );
611
+ assert (rgn -> base == r2 .base );
612
+
613
+ assert (memblock .reserved .cnt == 2 );
614
+ assert (memblock .reserved .total_size == total_size );
615
+
616
+ return 0 ;
617
+ }
618
+
619
+ /* Test case wrappers */
620
+ static int alloc_simple_check (void )
621
+ {
622
+ memblock_set_bottom_up (false);
419
623
alloc_top_down_simple_check ();
624
+ memblock_set_bottom_up (true);
625
+ alloc_bottom_up_simple_check ();
626
+
627
+ return 0 ;
628
+ }
629
+
630
+ static int alloc_disjoint_check (void )
631
+ {
632
+ memblock_set_bottom_up (false);
420
633
alloc_top_down_disjoint_check ();
634
+ memblock_set_bottom_up (true);
635
+ alloc_bottom_up_disjoint_check ();
636
+
637
+ return 0 ;
638
+ }
639
+
640
+ static int alloc_before_check (void )
641
+ {
642
+ memblock_set_bottom_up (false);
421
643
alloc_top_down_before_check ();
644
+ memblock_set_bottom_up (true);
645
+ alloc_bottom_up_before_check ();
646
+
647
+ return 0 ;
648
+ }
649
+
650
+ static int alloc_after_check (void )
651
+ {
652
+ memblock_set_bottom_up (false);
422
653
alloc_top_down_after_check ();
423
- alloc_top_down_second_fit_check ();
654
+ memblock_set_bottom_up (true);
655
+ alloc_bottom_up_after_check ();
656
+
657
+ return 0 ;
658
+ }
659
+
660
+ static int alloc_in_between_check (void )
661
+ {
662
+ memblock_set_bottom_up (false);
424
663
alloc_in_between_generic_check ();
664
+ memblock_set_bottom_up (true);
665
+ alloc_in_between_generic_check ();
666
+
667
+ return 0 ;
668
+ }
669
+
670
+ static int alloc_second_fit_check (void )
671
+ {
672
+ memblock_set_bottom_up (false);
673
+ alloc_top_down_second_fit_check ();
674
+ memblock_set_bottom_up (true);
675
+ alloc_bottom_up_second_fit_check ();
676
+
677
+ return 0 ;
678
+ }
679
+
680
+ static int alloc_small_gaps_check (void )
681
+ {
682
+ memblock_set_bottom_up (false);
425
683
alloc_small_gaps_generic_check ();
684
+ memblock_set_bottom_up (true);
685
+ alloc_small_gaps_generic_check ();
686
+
687
+ return 0 ;
688
+ }
689
+
690
+ static int alloc_all_reserved_check (void )
691
+ {
692
+ memblock_set_bottom_up (false);
693
+ alloc_all_reserved_generic_check ();
694
+ memblock_set_bottom_up (true);
426
695
alloc_all_reserved_generic_check ();
696
+
697
+ return 0 ;
698
+ }
699
+
700
+ static int alloc_no_space_check (void )
701
+ {
702
+ memblock_set_bottom_up (false);
703
+ alloc_no_space_generic_check ();
704
+ memblock_set_bottom_up (true);
427
705
alloc_no_space_generic_check ();
706
+
707
+ return 0 ;
708
+ }
709
+
710
+ static int alloc_limited_space_check (void )
711
+ {
712
+ memblock_set_bottom_up (false);
428
713
alloc_limited_space_generic_check ();
714
+ memblock_set_bottom_up (true);
715
+ alloc_limited_space_generic_check ();
716
+
717
+ return 0 ;
718
+ }
719
+
720
+ static int alloc_no_memory_check (void )
721
+ {
722
+ memblock_set_bottom_up (false);
723
+ alloc_no_memory_generic_check ();
724
+ memblock_set_bottom_up (true);
429
725
alloc_no_memory_generic_check ();
430
726
727
+ return 0 ;
728
+ }
729
+
730
+ int memblock_alloc_checks (void )
731
+ {
732
+ reset_memblock_attributes ();
733
+ dummy_physical_memory_init ();
734
+
735
+ alloc_simple_check ();
736
+ alloc_disjoint_check ();
737
+ alloc_before_check ();
738
+ alloc_after_check ();
739
+ alloc_second_fit_check ();
740
+ alloc_small_gaps_check ();
741
+ alloc_in_between_check ();
742
+ alloc_all_reserved_check ();
743
+ alloc_no_space_check ();
744
+ alloc_limited_space_check ();
745
+ alloc_no_memory_check ();
746
+
431
747
dummy_physical_memory_cleanup ();
432
748
433
749
return 0 ;
0 commit comments