@@ -982,6 +982,112 @@ static int memblock_reserve_many_check(void)
982
982
return 0 ;
983
983
}
984
984
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
+
985
1091
static int memblock_reserve_checks (void )
986
1092
{
987
1093
prefix_reset ();
@@ -997,6 +1103,7 @@ static int memblock_reserve_checks(void)
997
1103
memblock_reserve_between_check ();
998
1104
memblock_reserve_near_max_check ();
999
1105
memblock_reserve_many_check ();
1106
+ memblock_reserve_all_locations_check ();
1000
1107
1001
1108
prefix_pop ();
1002
1109
0 commit comments