Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memblock test: Add test to memblock_reserve() 129th region

Reserve 129th region in the memblock, and this will trigger the
memblock_double_array() function, this needs valid memory regions. So
using dummy_physical_memory_init() to allocate a valid memory region.
At the same time, reserve 128 faked memory region, and make sure these
reserved region not intersect with the valid memory region. So
memblock_double_array() will choose the valid memory region, and it will
success.

Also need to restore the reserved.regions after memblock_double_array(),
to make sure the subsequent tests can run as normal.

Signed-off-by: Shaoqin Huang <shaoqin.huang@intel.com>
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Link: https://lore.kernel.org/r/20221011062128.49359-3-shaoqin.huang@intel.com

authored by

Shaoqin Huang and committed by
Mike Rapoport
5b27dd79 085bdaa6

+91
+91
tools/testing/memblock/tests/basic_api.c
··· 892 892 return 0; 893 893 } 894 894 895 + /* 896 + * A test that trying to reserve the 129th memory block. 897 + * Expect to trigger memblock_double_array() to double the 898 + * memblock.memory.max, find a new valid memory as 899 + * reserved.regions. 900 + */ 901 + static int memblock_reserve_many_check(void) 902 + { 903 + int i; 904 + void *orig_region; 905 + struct region r = { 906 + .base = SZ_16K, 907 + .size = SZ_16K, 908 + }; 909 + phys_addr_t memory_base = SZ_128K; 910 + phys_addr_t new_reserved_regions_size; 911 + 912 + PREFIX_PUSH(); 913 + 914 + reset_memblock_regions(); 915 + memblock_allow_resize(); 916 + 917 + /* Add a valid memory region used by double_array(). */ 918 + dummy_physical_memory_init(); 919 + memblock_add(dummy_physical_memory_base(), MEM_SIZE); 920 + 921 + for (i = 0; i < INIT_MEMBLOCK_REGIONS; i++) { 922 + /* Reserve some fakes memory region to fulfill the memblock. */ 923 + memblock_reserve(memory_base, MEM_SIZE); 924 + 925 + ASSERT_EQ(memblock.reserved.cnt, i + 1); 926 + ASSERT_EQ(memblock.reserved.total_size, (i + 1) * MEM_SIZE); 927 + 928 + /* Keep the gap so these memory region will not be merged. */ 929 + memory_base += MEM_SIZE * 2; 930 + } 931 + 932 + orig_region = memblock.reserved.regions; 933 + 934 + /* This reserve the 129 memory_region, and makes it double array. */ 935 + memblock_reserve(memory_base, MEM_SIZE); 936 + 937 + /* 938 + * This is the memory region size used by the doubled reserved.regions, 939 + * and it has been reserved due to it has been used. The size is used to 940 + * calculate the total_size that the memblock.reserved have now. 941 + */ 942 + new_reserved_regions_size = PAGE_ALIGN((INIT_MEMBLOCK_REGIONS * 2) * 943 + sizeof(struct memblock_region)); 944 + /* 945 + * The double_array() will find a free memory region as the new 946 + * reserved.regions, and the used memory region will be reserved, so 947 + * there will be one more region exist in the reserved memblock. And the 948 + * one more reserved region's size is new_reserved_regions_size. 949 + */ 950 + ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 2); 951 + ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE + 952 + new_reserved_regions_size); 953 + ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2); 954 + 955 + /* 956 + * Now memblock_double_array() works fine. Let's check after the 957 + * double_array(), the memblock_reserve() still works as normal. 958 + */ 959 + memblock_reserve(r.base, r.size); 960 + ASSERT_EQ(memblock.reserved.regions[0].base, r.base); 961 + ASSERT_EQ(memblock.reserved.regions[0].size, r.size); 962 + 963 + ASSERT_EQ(memblock.reserved.cnt, INIT_MEMBLOCK_REGIONS + 3); 964 + ASSERT_EQ(memblock.reserved.total_size, (INIT_MEMBLOCK_REGIONS + 1) * MEM_SIZE + 965 + new_reserved_regions_size + 966 + r.size); 967 + ASSERT_EQ(memblock.reserved.max, INIT_MEMBLOCK_REGIONS * 2); 968 + 969 + dummy_physical_memory_cleanup(); 970 + 971 + /* 972 + * The current reserved.regions is occupying a range of memory that 973 + * allocated from dummy_physical_memory_init(). After free the memory, 974 + * we must not use it. So restore the origin memory region to make sure 975 + * the tests can run as normal and not affected by the double array. 976 + */ 977 + memblock.reserved.regions = orig_region; 978 + memblock.reserved.cnt = INIT_MEMBLOCK_RESERVED_REGIONS; 979 + 980 + test_pass_pop(); 981 + 982 + return 0; 983 + } 984 + 895 985 static int memblock_reserve_checks(void) 896 986 { 897 987 prefix_reset(); ··· 996 906 memblock_reserve_twice_check(); 997 907 memblock_reserve_between_check(); 998 908 memblock_reserve_near_max_check(); 909 + memblock_reserve_many_check(); 999 910 1000 911 prefix_pop(); 1001 912