162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci#include "alloc_nid_api.h" 362306a36Sopenharmony_ci 462306a36Sopenharmony_cistatic int alloc_nid_test_flags = TEST_F_NONE; 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * contains the fraction of MEM_SIZE contained in each node in basis point 862306a36Sopenharmony_ci * units (one hundredth of 1% or 1/10000) 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_cistatic const unsigned int node_fractions[] = { 1162306a36Sopenharmony_ci 2500, /* 1/4 */ 1262306a36Sopenharmony_ci 625, /* 1/16 */ 1362306a36Sopenharmony_ci 1250, /* 1/8 */ 1462306a36Sopenharmony_ci 1250, /* 1/8 */ 1562306a36Sopenharmony_ci 625, /* 1/16 */ 1662306a36Sopenharmony_ci 625, /* 1/16 */ 1762306a36Sopenharmony_ci 2500, /* 1/4 */ 1862306a36Sopenharmony_ci 625, /* 1/16 */ 1962306a36Sopenharmony_ci}; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic inline const char * const get_memblock_alloc_nid_name(int flags) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci if (flags & TEST_F_EXACT) 2462306a36Sopenharmony_ci return "memblock_alloc_exact_nid_raw"; 2562306a36Sopenharmony_ci if (flags & TEST_F_RAW) 2662306a36Sopenharmony_ci return "memblock_alloc_try_nid_raw"; 2762306a36Sopenharmony_ci return "memblock_alloc_try_nid"; 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic inline void *run_memblock_alloc_nid(phys_addr_t size, 3162306a36Sopenharmony_ci phys_addr_t align, 3262306a36Sopenharmony_ci phys_addr_t min_addr, 3362306a36Sopenharmony_ci phys_addr_t max_addr, int nid) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci assert(!(alloc_nid_test_flags & TEST_F_EXACT) || 3662306a36Sopenharmony_ci (alloc_nid_test_flags & TEST_F_RAW)); 3762306a36Sopenharmony_ci /* 3862306a36Sopenharmony_ci * TEST_F_EXACT should be checked before TEST_F_RAW since 3962306a36Sopenharmony_ci * memblock_alloc_exact_nid_raw() performs raw allocations. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ci if (alloc_nid_test_flags & TEST_F_EXACT) 4262306a36Sopenharmony_ci return memblock_alloc_exact_nid_raw(size, align, min_addr, 4362306a36Sopenharmony_ci max_addr, nid); 4462306a36Sopenharmony_ci if (alloc_nid_test_flags & TEST_F_RAW) 4562306a36Sopenharmony_ci return memblock_alloc_try_nid_raw(size, align, min_addr, 4662306a36Sopenharmony_ci max_addr, nid); 4762306a36Sopenharmony_ci return memblock_alloc_try_nid(size, align, min_addr, max_addr, nid); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* 5162306a36Sopenharmony_ci * A simple test that tries to allocate a memory region within min_addr and 5262306a36Sopenharmony_ci * max_addr range: 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * + + 5562306a36Sopenharmony_ci * | + +-----------+ | 5662306a36Sopenharmony_ci * | | | rgn | | 5762306a36Sopenharmony_ci * +----+-------+-----------+------+ 5862306a36Sopenharmony_ci * ^ ^ 5962306a36Sopenharmony_ci * | | 6062306a36Sopenharmony_ci * min_addr max_addr 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * Expect to allocate a region that ends at max_addr. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_cistatic int alloc_nid_top_down_simple_check(void) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 6762306a36Sopenharmony_ci void *allocated_ptr = NULL; 6862306a36Sopenharmony_ci phys_addr_t size = SZ_128; 6962306a36Sopenharmony_ci phys_addr_t min_addr; 7062306a36Sopenharmony_ci phys_addr_t max_addr; 7162306a36Sopenharmony_ci phys_addr_t rgn_end; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci PREFIX_PUSH(); 7462306a36Sopenharmony_ci setup_memblock(); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2; 7762306a36Sopenharmony_ci max_addr = min_addr + SZ_512; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 8062306a36Sopenharmony_ci min_addr, max_addr, 8162306a36Sopenharmony_ci NUMA_NO_NODE); 8262306a36Sopenharmony_ci rgn_end = rgn->base + rgn->size; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 8562306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 8862306a36Sopenharmony_ci ASSERT_EQ(rgn->base, max_addr - size); 8962306a36Sopenharmony_ci ASSERT_EQ(rgn_end, max_addr); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 9262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci test_pass_pop(); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci return 0; 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* 10062306a36Sopenharmony_ci * A simple test that tries to allocate a memory region within min_addr and 10162306a36Sopenharmony_ci * max_addr range, where the end address is misaligned: 10262306a36Sopenharmony_ci * 10362306a36Sopenharmony_ci * + + + 10462306a36Sopenharmony_ci * | + +---------+ + | 10562306a36Sopenharmony_ci * | | | rgn | | | 10662306a36Sopenharmony_ci * +------+-------+---------+--+----+ 10762306a36Sopenharmony_ci * ^ ^ ^ 10862306a36Sopenharmony_ci * | | | 10962306a36Sopenharmony_ci * min_add | max_addr 11062306a36Sopenharmony_ci * | 11162306a36Sopenharmony_ci * Aligned address 11262306a36Sopenharmony_ci * boundary 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * Expect to allocate an aligned region that ends before max_addr. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_cistatic int alloc_nid_top_down_end_misaligned_check(void) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 11962306a36Sopenharmony_ci void *allocated_ptr = NULL; 12062306a36Sopenharmony_ci phys_addr_t size = SZ_128; 12162306a36Sopenharmony_ci phys_addr_t misalign = SZ_2; 12262306a36Sopenharmony_ci phys_addr_t min_addr; 12362306a36Sopenharmony_ci phys_addr_t max_addr; 12462306a36Sopenharmony_ci phys_addr_t rgn_end; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci PREFIX_PUSH(); 12762306a36Sopenharmony_ci setup_memblock(); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2; 13062306a36Sopenharmony_ci max_addr = min_addr + SZ_512 + misalign; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 13362306a36Sopenharmony_ci min_addr, max_addr, 13462306a36Sopenharmony_ci NUMA_NO_NODE); 13562306a36Sopenharmony_ci rgn_end = rgn->base + rgn->size; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 13862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 14162306a36Sopenharmony_ci ASSERT_EQ(rgn->base, max_addr - size - misalign); 14262306a36Sopenharmony_ci ASSERT_LT(rgn_end, max_addr); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 14562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci test_pass_pop(); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci return 0; 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci/* 15362306a36Sopenharmony_ci * A simple test that tries to allocate a memory region, which spans over the 15462306a36Sopenharmony_ci * min_addr and max_addr range: 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * + + 15762306a36Sopenharmony_ci * | +---------------+ | 15862306a36Sopenharmony_ci * | | rgn | | 15962306a36Sopenharmony_ci * +------+---------------+-------+ 16062306a36Sopenharmony_ci * ^ ^ 16162306a36Sopenharmony_ci * | | 16262306a36Sopenharmony_ci * min_addr max_addr 16362306a36Sopenharmony_ci * 16462306a36Sopenharmony_ci * Expect to allocate a region that starts at min_addr and ends at 16562306a36Sopenharmony_ci * max_addr, given that min_addr is aligned. 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_cistatic int alloc_nid_exact_address_generic_check(void) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 17062306a36Sopenharmony_ci void *allocated_ptr = NULL; 17162306a36Sopenharmony_ci phys_addr_t size = SZ_1K; 17262306a36Sopenharmony_ci phys_addr_t min_addr; 17362306a36Sopenharmony_ci phys_addr_t max_addr; 17462306a36Sopenharmony_ci phys_addr_t rgn_end; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci PREFIX_PUSH(); 17762306a36Sopenharmony_ci setup_memblock(); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES; 18062306a36Sopenharmony_ci max_addr = min_addr + size; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 18362306a36Sopenharmony_ci min_addr, max_addr, 18462306a36Sopenharmony_ci NUMA_NO_NODE); 18562306a36Sopenharmony_ci rgn_end = rgn->base + rgn->size; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 18862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 19162306a36Sopenharmony_ci ASSERT_EQ(rgn->base, min_addr); 19262306a36Sopenharmony_ci ASSERT_EQ(rgn_end, max_addr); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 19562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci test_pass_pop(); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci return 0; 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci/* 20362306a36Sopenharmony_ci * A test that tries to allocate a memory region, which can't fit into 20462306a36Sopenharmony_ci * min_addr and max_addr range: 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * + + + 20762306a36Sopenharmony_ci * | +----------+-----+ | 20862306a36Sopenharmony_ci * | | rgn + | | 20962306a36Sopenharmony_ci * +--------+----------+-----+----+ 21062306a36Sopenharmony_ci * ^ ^ ^ 21162306a36Sopenharmony_ci * | | | 21262306a36Sopenharmony_ci * Aligned | max_addr 21362306a36Sopenharmony_ci * address | 21462306a36Sopenharmony_ci * boundary min_add 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region which 21762306a36Sopenharmony_ci * ends at max_addr (if the address is aligned). 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_cistatic int alloc_nid_top_down_narrow_range_check(void) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 22262306a36Sopenharmony_ci void *allocated_ptr = NULL; 22362306a36Sopenharmony_ci phys_addr_t size = SZ_256; 22462306a36Sopenharmony_ci phys_addr_t min_addr; 22562306a36Sopenharmony_ci phys_addr_t max_addr; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci PREFIX_PUSH(); 22862306a36Sopenharmony_ci setup_memblock(); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SZ_512; 23162306a36Sopenharmony_ci max_addr = min_addr + SMP_CACHE_BYTES; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 23462306a36Sopenharmony_ci min_addr, max_addr, 23562306a36Sopenharmony_ci NUMA_NO_NODE); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 23862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 24162306a36Sopenharmony_ci ASSERT_EQ(rgn->base, max_addr - size); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 24462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci test_pass_pop(); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci return 0; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/* 25262306a36Sopenharmony_ci * A test that tries to allocate a memory region, which can't fit into 25362306a36Sopenharmony_ci * min_addr and max_addr range, with the latter being too close to the beginning 25462306a36Sopenharmony_ci * of the available memory: 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci * +-------------+ 25762306a36Sopenharmony_ci * | new | 25862306a36Sopenharmony_ci * +-------------+ 25962306a36Sopenharmony_ci * + + 26062306a36Sopenharmony_ci * | + | 26162306a36Sopenharmony_ci * | | | 26262306a36Sopenharmony_ci * +-------+--------------+ 26362306a36Sopenharmony_ci * ^ ^ 26462306a36Sopenharmony_ci * | | 26562306a36Sopenharmony_ci * | max_addr 26662306a36Sopenharmony_ci * | 26762306a36Sopenharmony_ci * min_addr 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * Expect no allocation to happen. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_cistatic int alloc_nid_low_max_generic_check(void) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci void *allocated_ptr = NULL; 27462306a36Sopenharmony_ci phys_addr_t size = SZ_1K; 27562306a36Sopenharmony_ci phys_addr_t min_addr; 27662306a36Sopenharmony_ci phys_addr_t max_addr; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci PREFIX_PUSH(); 27962306a36Sopenharmony_ci setup_memblock(); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 28262306a36Sopenharmony_ci max_addr = min_addr + SMP_CACHE_BYTES; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 28562306a36Sopenharmony_ci min_addr, max_addr, 28662306a36Sopenharmony_ci NUMA_NO_NODE); 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci test_pass_pop(); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci return 0; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/* 29662306a36Sopenharmony_ci * A test that tries to allocate a memory region within min_addr min_addr range, 29762306a36Sopenharmony_ci * with min_addr being so close that it's next to an allocated region: 29862306a36Sopenharmony_ci * 29962306a36Sopenharmony_ci * + + 30062306a36Sopenharmony_ci * | +--------+---------------| 30162306a36Sopenharmony_ci * | | r1 | rgn | 30262306a36Sopenharmony_ci * +-------+--------+---------------+ 30362306a36Sopenharmony_ci * ^ ^ 30462306a36Sopenharmony_ci * | | 30562306a36Sopenharmony_ci * min_addr max_addr 30662306a36Sopenharmony_ci * 30762306a36Sopenharmony_ci * Expect a merge of both regions. Only the region size gets updated. 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_cistatic int alloc_nid_min_reserved_generic_check(void) 31062306a36Sopenharmony_ci{ 31162306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 31262306a36Sopenharmony_ci void *allocated_ptr = NULL; 31362306a36Sopenharmony_ci phys_addr_t r1_size = SZ_128; 31462306a36Sopenharmony_ci phys_addr_t r2_size = SZ_64; 31562306a36Sopenharmony_ci phys_addr_t total_size = r1_size + r2_size; 31662306a36Sopenharmony_ci phys_addr_t min_addr; 31762306a36Sopenharmony_ci phys_addr_t max_addr; 31862306a36Sopenharmony_ci phys_addr_t reserved_base; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci PREFIX_PUSH(); 32162306a36Sopenharmony_ci setup_memblock(); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 32462306a36Sopenharmony_ci min_addr = max_addr - r2_size; 32562306a36Sopenharmony_ci reserved_base = min_addr - r1_size; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci memblock_reserve(reserved_base, r1_size); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r2_size, SMP_CACHE_BYTES, 33062306a36Sopenharmony_ci min_addr, max_addr, 33162306a36Sopenharmony_ci NUMA_NO_NODE); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 33462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_nid_test_flags); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 33762306a36Sopenharmony_ci ASSERT_EQ(rgn->base, reserved_base); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 34062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci test_pass_pop(); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci return 0; 34562306a36Sopenharmony_ci} 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci/* 34862306a36Sopenharmony_ci * A test that tries to allocate a memory region within min_addr and max_addr, 34962306a36Sopenharmony_ci * with max_addr being so close that it's next to an allocated region: 35062306a36Sopenharmony_ci * 35162306a36Sopenharmony_ci * + + 35262306a36Sopenharmony_ci * | +-------------+--------| 35362306a36Sopenharmony_ci * | | rgn | r1 | 35462306a36Sopenharmony_ci * +----------+-------------+--------+ 35562306a36Sopenharmony_ci * ^ ^ 35662306a36Sopenharmony_ci * | | 35762306a36Sopenharmony_ci * min_addr max_addr 35862306a36Sopenharmony_ci * 35962306a36Sopenharmony_ci * Expect a merge of regions. Only the region size gets updated. 36062306a36Sopenharmony_ci */ 36162306a36Sopenharmony_cistatic int alloc_nid_max_reserved_generic_check(void) 36262306a36Sopenharmony_ci{ 36362306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 36462306a36Sopenharmony_ci void *allocated_ptr = NULL; 36562306a36Sopenharmony_ci phys_addr_t r1_size = SZ_64; 36662306a36Sopenharmony_ci phys_addr_t r2_size = SZ_128; 36762306a36Sopenharmony_ci phys_addr_t total_size = r1_size + r2_size; 36862306a36Sopenharmony_ci phys_addr_t min_addr; 36962306a36Sopenharmony_ci phys_addr_t max_addr; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci PREFIX_PUSH(); 37262306a36Sopenharmony_ci setup_memblock(); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM() - r1_size; 37562306a36Sopenharmony_ci min_addr = max_addr - r2_size; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci memblock_reserve(max_addr, r1_size); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r2_size, SMP_CACHE_BYTES, 38062306a36Sopenharmony_ci min_addr, max_addr, 38162306a36Sopenharmony_ci NUMA_NO_NODE); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 38462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_nid_test_flags); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 38762306a36Sopenharmony_ci ASSERT_EQ(rgn->base, min_addr); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 39062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci test_pass_pop(); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci return 0; 39562306a36Sopenharmony_ci} 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci/* 39862306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, when 39962306a36Sopenharmony_ci * there are two reserved regions at the borders, with a gap big enough to fit 40062306a36Sopenharmony_ci * a new region: 40162306a36Sopenharmony_ci * 40262306a36Sopenharmony_ci * + + 40362306a36Sopenharmony_ci * | +--------+ +-------+------+ | 40462306a36Sopenharmony_ci * | | r2 | | rgn | r1 | | 40562306a36Sopenharmony_ci * +----+--------+---+-------+------+--+ 40662306a36Sopenharmony_ci * ^ ^ 40762306a36Sopenharmony_ci * | | 40862306a36Sopenharmony_ci * min_addr max_addr 40962306a36Sopenharmony_ci * 41062306a36Sopenharmony_ci * Expect to merge the new region with r1. The second region does not get 41162306a36Sopenharmony_ci * updated. The total size field gets updated. 41262306a36Sopenharmony_ci */ 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic int alloc_nid_top_down_reserved_with_space_check(void) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[1]; 41762306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[0]; 41862306a36Sopenharmony_ci void *allocated_ptr = NULL; 41962306a36Sopenharmony_ci struct region r1, r2; 42062306a36Sopenharmony_ci phys_addr_t r3_size = SZ_64; 42162306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 42262306a36Sopenharmony_ci phys_addr_t total_size; 42362306a36Sopenharmony_ci phys_addr_t max_addr; 42462306a36Sopenharmony_ci phys_addr_t min_addr; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci PREFIX_PUSH(); 42762306a36Sopenharmony_ci setup_memblock(); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; 43062306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci r2.size = SZ_128; 43362306a36Sopenharmony_ci r2.base = r1.base - (r3_size + gap_size + r2.size); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 43662306a36Sopenharmony_ci min_addr = r2.base + r2.size; 43762306a36Sopenharmony_ci max_addr = r1.base; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 44062306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 44362306a36Sopenharmony_ci min_addr, max_addr, 44462306a36Sopenharmony_ci NUMA_NO_NODE); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 44762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size + r3_size); 45062306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, max_addr - r3_size); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2.size); 45362306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, r2.base); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 45662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci test_pass_pop(); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci return 0; 46162306a36Sopenharmony_ci} 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci/* 46462306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, when 46562306a36Sopenharmony_ci * there are two reserved regions at the borders, with a gap of a size equal to 46662306a36Sopenharmony_ci * the size of the new region: 46762306a36Sopenharmony_ci * 46862306a36Sopenharmony_ci * + + 46962306a36Sopenharmony_ci * | +--------+--------+--------+ | 47062306a36Sopenharmony_ci * | | r2 | r3 | r1 | | 47162306a36Sopenharmony_ci * +-----+--------+--------+--------+-----+ 47262306a36Sopenharmony_ci * ^ ^ 47362306a36Sopenharmony_ci * | | 47462306a36Sopenharmony_ci * min_addr max_addr 47562306a36Sopenharmony_ci * 47662306a36Sopenharmony_ci * Expect to merge all of the regions into one. The region counter and total 47762306a36Sopenharmony_ci * size fields get updated. 47862306a36Sopenharmony_ci */ 47962306a36Sopenharmony_cistatic int alloc_nid_reserved_full_merge_generic_check(void) 48062306a36Sopenharmony_ci{ 48162306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 48262306a36Sopenharmony_ci void *allocated_ptr = NULL; 48362306a36Sopenharmony_ci struct region r1, r2; 48462306a36Sopenharmony_ci phys_addr_t r3_size = SZ_64; 48562306a36Sopenharmony_ci phys_addr_t total_size; 48662306a36Sopenharmony_ci phys_addr_t max_addr; 48762306a36Sopenharmony_ci phys_addr_t min_addr; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci PREFIX_PUSH(); 49062306a36Sopenharmony_ci setup_memblock(); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; 49362306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci r2.size = SZ_128; 49662306a36Sopenharmony_ci r2.base = r1.base - (r3_size + r2.size); 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 49962306a36Sopenharmony_ci min_addr = r2.base + r2.size; 50062306a36Sopenharmony_ci max_addr = r1.base; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 50362306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 50662306a36Sopenharmony_ci min_addr, max_addr, 50762306a36Sopenharmony_ci NUMA_NO_NODE); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 51062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 51362306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r2.base); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 51662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci test_pass_pop(); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci return 0; 52162306a36Sopenharmony_ci} 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci/* 52462306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, when 52562306a36Sopenharmony_ci * there are two reserved regions at the borders, with a gap that can't fit 52662306a36Sopenharmony_ci * a new region: 52762306a36Sopenharmony_ci * 52862306a36Sopenharmony_ci * + + 52962306a36Sopenharmony_ci * | +----------+------+ +------+ | 53062306a36Sopenharmony_ci * | | r3 | r2 | | r1 | | 53162306a36Sopenharmony_ci * +--+----------+------+----+------+---+ 53262306a36Sopenharmony_ci * ^ ^ 53362306a36Sopenharmony_ci * | | 53462306a36Sopenharmony_ci * | max_addr 53562306a36Sopenharmony_ci * | 53662306a36Sopenharmony_ci * min_addr 53762306a36Sopenharmony_ci * 53862306a36Sopenharmony_ci * Expect to merge the new region with r2. The second region does not get 53962306a36Sopenharmony_ci * updated. The total size counter gets updated. 54062306a36Sopenharmony_ci */ 54162306a36Sopenharmony_cistatic int alloc_nid_top_down_reserved_no_space_check(void) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[1]; 54462306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[0]; 54562306a36Sopenharmony_ci void *allocated_ptr = NULL; 54662306a36Sopenharmony_ci struct region r1, r2; 54762306a36Sopenharmony_ci phys_addr_t r3_size = SZ_256; 54862306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 54962306a36Sopenharmony_ci phys_addr_t total_size; 55062306a36Sopenharmony_ci phys_addr_t max_addr; 55162306a36Sopenharmony_ci phys_addr_t min_addr; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci PREFIX_PUSH(); 55462306a36Sopenharmony_ci setup_memblock(); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; 55762306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci r2.size = SZ_128; 56062306a36Sopenharmony_ci r2.base = r1.base - (r2.size + gap_size); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 56362306a36Sopenharmony_ci min_addr = r2.base + r2.size; 56462306a36Sopenharmony_ci max_addr = r1.base; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 56762306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 57062306a36Sopenharmony_ci min_addr, max_addr, 57162306a36Sopenharmony_ci NUMA_NO_NODE); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 57462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size); 57762306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, r1.base); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2.size + r3_size); 58062306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, r2.base - r3_size); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 58362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci test_pass_pop(); 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci return 0; 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci/* 59162306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, but 59262306a36Sopenharmony_ci * it's too narrow and everything else is reserved: 59362306a36Sopenharmony_ci * 59462306a36Sopenharmony_ci * +-----------+ 59562306a36Sopenharmony_ci * | new | 59662306a36Sopenharmony_ci * +-----------+ 59762306a36Sopenharmony_ci * + + 59862306a36Sopenharmony_ci * |--------------+ +----------| 59962306a36Sopenharmony_ci * | r2 | | r1 | 60062306a36Sopenharmony_ci * +--------------+------+----------+ 60162306a36Sopenharmony_ci * ^ ^ 60262306a36Sopenharmony_ci * | | 60362306a36Sopenharmony_ci * | max_addr 60462306a36Sopenharmony_ci * | 60562306a36Sopenharmony_ci * min_addr 60662306a36Sopenharmony_ci * 60762306a36Sopenharmony_ci * Expect no allocation to happen. 60862306a36Sopenharmony_ci */ 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic int alloc_nid_reserved_all_generic_check(void) 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci void *allocated_ptr = NULL; 61362306a36Sopenharmony_ci struct region r1, r2; 61462306a36Sopenharmony_ci phys_addr_t r3_size = SZ_256; 61562306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 61662306a36Sopenharmony_ci phys_addr_t max_addr; 61762306a36Sopenharmony_ci phys_addr_t min_addr; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci PREFIX_PUSH(); 62062306a36Sopenharmony_ci setup_memblock(); 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES; 62362306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci r2.size = MEM_SIZE - (r1.size + gap_size); 62662306a36Sopenharmony_ci r2.base = memblock_start_of_DRAM(); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci min_addr = r2.base + r2.size; 62962306a36Sopenharmony_ci max_addr = r1.base; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 63262306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 63562306a36Sopenharmony_ci min_addr, max_addr, 63662306a36Sopenharmony_ci NUMA_NO_NODE); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci test_pass_pop(); 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci return 0; 64362306a36Sopenharmony_ci} 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci/* 64662306a36Sopenharmony_ci * A test that tries to allocate a memory region, where max_addr is 64762306a36Sopenharmony_ci * bigger than the end address of the available memory. Expect to allocate 64862306a36Sopenharmony_ci * a region that ends before the end of the memory. 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_cistatic int alloc_nid_top_down_cap_max_check(void) 65162306a36Sopenharmony_ci{ 65262306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 65362306a36Sopenharmony_ci void *allocated_ptr = NULL; 65462306a36Sopenharmony_ci phys_addr_t size = SZ_256; 65562306a36Sopenharmony_ci phys_addr_t min_addr; 65662306a36Sopenharmony_ci phys_addr_t max_addr; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci PREFIX_PUSH(); 65962306a36Sopenharmony_ci setup_memblock(); 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci min_addr = memblock_end_of_DRAM() - SZ_1K; 66262306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM() + SZ_256; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 66562306a36Sopenharmony_ci min_addr, max_addr, 66662306a36Sopenharmony_ci NUMA_NO_NODE); 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 66962306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 67262306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - size); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 67562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci test_pass_pop(); 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci return 0; 68062306a36Sopenharmony_ci} 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci/* 68362306a36Sopenharmony_ci * A test that tries to allocate a memory region, where min_addr is 68462306a36Sopenharmony_ci * smaller than the start address of the available memory. Expect to allocate 68562306a36Sopenharmony_ci * a region that ends before the end of the memory. 68662306a36Sopenharmony_ci */ 68762306a36Sopenharmony_cistatic int alloc_nid_top_down_cap_min_check(void) 68862306a36Sopenharmony_ci{ 68962306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 69062306a36Sopenharmony_ci void *allocated_ptr = NULL; 69162306a36Sopenharmony_ci phys_addr_t size = SZ_1K; 69262306a36Sopenharmony_ci phys_addr_t min_addr; 69362306a36Sopenharmony_ci phys_addr_t max_addr; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci PREFIX_PUSH(); 69662306a36Sopenharmony_ci setup_memblock(); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() - SZ_256; 69962306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 70262306a36Sopenharmony_ci min_addr, max_addr, 70362306a36Sopenharmony_ci NUMA_NO_NODE); 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 70662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 70962306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - size); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 71262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci test_pass_pop(); 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci return 0; 71762306a36Sopenharmony_ci} 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci/* 72062306a36Sopenharmony_ci * A simple test that tries to allocate a memory region within min_addr and 72162306a36Sopenharmony_ci * max_addr range: 72262306a36Sopenharmony_ci * 72362306a36Sopenharmony_ci * + + 72462306a36Sopenharmony_ci * | +-----------+ | | 72562306a36Sopenharmony_ci * | | rgn | | | 72662306a36Sopenharmony_ci * +----+-----------+-----------+------+ 72762306a36Sopenharmony_ci * ^ ^ 72862306a36Sopenharmony_ci * | | 72962306a36Sopenharmony_ci * min_addr max_addr 73062306a36Sopenharmony_ci * 73162306a36Sopenharmony_ci * Expect to allocate a region that ends before max_addr. 73262306a36Sopenharmony_ci */ 73362306a36Sopenharmony_cistatic int alloc_nid_bottom_up_simple_check(void) 73462306a36Sopenharmony_ci{ 73562306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 73662306a36Sopenharmony_ci void *allocated_ptr = NULL; 73762306a36Sopenharmony_ci phys_addr_t size = SZ_128; 73862306a36Sopenharmony_ci phys_addr_t min_addr; 73962306a36Sopenharmony_ci phys_addr_t max_addr; 74062306a36Sopenharmony_ci phys_addr_t rgn_end; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci PREFIX_PUSH(); 74362306a36Sopenharmony_ci setup_memblock(); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2; 74662306a36Sopenharmony_ci max_addr = min_addr + SZ_512; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 74962306a36Sopenharmony_ci min_addr, max_addr, 75062306a36Sopenharmony_ci NUMA_NO_NODE); 75162306a36Sopenharmony_ci rgn_end = rgn->base + rgn->size; 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 75462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 75762306a36Sopenharmony_ci ASSERT_EQ(rgn->base, min_addr); 75862306a36Sopenharmony_ci ASSERT_LT(rgn_end, max_addr); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 76162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci test_pass_pop(); 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci return 0; 76662306a36Sopenharmony_ci} 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci/* 76962306a36Sopenharmony_ci * A simple test that tries to allocate a memory region within min_addr and 77062306a36Sopenharmony_ci * max_addr range, where the start address is misaligned: 77162306a36Sopenharmony_ci * 77262306a36Sopenharmony_ci * + + 77362306a36Sopenharmony_ci * | + +-----------+ + | 77462306a36Sopenharmony_ci * | | | rgn | | | 77562306a36Sopenharmony_ci * +-----+---+-----------+-----+-----+ 77662306a36Sopenharmony_ci * ^ ^----. ^ 77762306a36Sopenharmony_ci * | | | 77862306a36Sopenharmony_ci * min_add | max_addr 77962306a36Sopenharmony_ci * | 78062306a36Sopenharmony_ci * Aligned address 78162306a36Sopenharmony_ci * boundary 78262306a36Sopenharmony_ci * 78362306a36Sopenharmony_ci * Expect to allocate an aligned region that ends before max_addr. 78462306a36Sopenharmony_ci */ 78562306a36Sopenharmony_cistatic int alloc_nid_bottom_up_start_misaligned_check(void) 78662306a36Sopenharmony_ci{ 78762306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 78862306a36Sopenharmony_ci void *allocated_ptr = NULL; 78962306a36Sopenharmony_ci phys_addr_t size = SZ_128; 79062306a36Sopenharmony_ci phys_addr_t misalign = SZ_2; 79162306a36Sopenharmony_ci phys_addr_t min_addr; 79262306a36Sopenharmony_ci phys_addr_t max_addr; 79362306a36Sopenharmony_ci phys_addr_t rgn_end; 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci PREFIX_PUSH(); 79662306a36Sopenharmony_ci setup_memblock(); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + misalign; 79962306a36Sopenharmony_ci max_addr = min_addr + SZ_512; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 80262306a36Sopenharmony_ci min_addr, max_addr, 80362306a36Sopenharmony_ci NUMA_NO_NODE); 80462306a36Sopenharmony_ci rgn_end = rgn->base + rgn->size; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 80762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 81062306a36Sopenharmony_ci ASSERT_EQ(rgn->base, min_addr + (SMP_CACHE_BYTES - misalign)); 81162306a36Sopenharmony_ci ASSERT_LT(rgn_end, max_addr); 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 81462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci test_pass_pop(); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci return 0; 81962306a36Sopenharmony_ci} 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci/* 82262306a36Sopenharmony_ci * A test that tries to allocate a memory region, which can't fit into min_addr 82362306a36Sopenharmony_ci * and max_addr range: 82462306a36Sopenharmony_ci * 82562306a36Sopenharmony_ci * + + 82662306a36Sopenharmony_ci * |---------+ + + | 82762306a36Sopenharmony_ci * | rgn | | | | 82862306a36Sopenharmony_ci * +---------+---------+----+------+ 82962306a36Sopenharmony_ci * ^ ^ 83062306a36Sopenharmony_ci * | | 83162306a36Sopenharmony_ci * | max_addr 83262306a36Sopenharmony_ci * | 83362306a36Sopenharmony_ci * min_add 83462306a36Sopenharmony_ci * 83562306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region which 83662306a36Sopenharmony_ci * starts at the beginning of the available memory. 83762306a36Sopenharmony_ci */ 83862306a36Sopenharmony_cistatic int alloc_nid_bottom_up_narrow_range_check(void) 83962306a36Sopenharmony_ci{ 84062306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 84162306a36Sopenharmony_ci void *allocated_ptr = NULL; 84262306a36Sopenharmony_ci phys_addr_t size = SZ_256; 84362306a36Sopenharmony_ci phys_addr_t min_addr; 84462306a36Sopenharmony_ci phys_addr_t max_addr; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci PREFIX_PUSH(); 84762306a36Sopenharmony_ci setup_memblock(); 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SZ_512; 85062306a36Sopenharmony_ci max_addr = min_addr + SMP_CACHE_BYTES; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 85362306a36Sopenharmony_ci min_addr, max_addr, 85462306a36Sopenharmony_ci NUMA_NO_NODE); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 85762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 86062306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_start_of_DRAM()); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 86362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci test_pass_pop(); 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci return 0; 86862306a36Sopenharmony_ci} 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci/* 87162306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, when 87262306a36Sopenharmony_ci * there are two reserved regions at the borders, with a gap big enough to fit 87362306a36Sopenharmony_ci * a new region: 87462306a36Sopenharmony_ci * 87562306a36Sopenharmony_ci * + + 87662306a36Sopenharmony_ci * | +--------+-------+ +------+ | 87762306a36Sopenharmony_ci * | | r2 | rgn | | r1 | | 87862306a36Sopenharmony_ci * +----+--------+-------+---+------+--+ 87962306a36Sopenharmony_ci * ^ ^ 88062306a36Sopenharmony_ci * | | 88162306a36Sopenharmony_ci * min_addr max_addr 88262306a36Sopenharmony_ci * 88362306a36Sopenharmony_ci * Expect to merge the new region with r2. The second region does not get 88462306a36Sopenharmony_ci * updated. The total size field gets updated. 88562306a36Sopenharmony_ci */ 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cistatic int alloc_nid_bottom_up_reserved_with_space_check(void) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[1]; 89062306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[0]; 89162306a36Sopenharmony_ci void *allocated_ptr = NULL; 89262306a36Sopenharmony_ci struct region r1, r2; 89362306a36Sopenharmony_ci phys_addr_t r3_size = SZ_64; 89462306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 89562306a36Sopenharmony_ci phys_addr_t total_size; 89662306a36Sopenharmony_ci phys_addr_t max_addr; 89762306a36Sopenharmony_ci phys_addr_t min_addr; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci PREFIX_PUSH(); 90062306a36Sopenharmony_ci setup_memblock(); 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; 90362306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci r2.size = SZ_128; 90662306a36Sopenharmony_ci r2.base = r1.base - (r3_size + gap_size + r2.size); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 90962306a36Sopenharmony_ci min_addr = r2.base + r2.size; 91062306a36Sopenharmony_ci max_addr = r1.base; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 91362306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 91662306a36Sopenharmony_ci min_addr, max_addr, 91762306a36Sopenharmony_ci NUMA_NO_NODE); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 92062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags); 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size); 92362306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, max_addr); 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2.size + r3_size); 92662306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, r2.base); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 92962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ci test_pass_pop(); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci return 0; 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci/* 93762306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, when 93862306a36Sopenharmony_ci * there are two reserved regions at the borders, with a gap of a size equal to 93962306a36Sopenharmony_ci * the size of the new region: 94062306a36Sopenharmony_ci * 94162306a36Sopenharmony_ci * + + 94262306a36Sopenharmony_ci * |----------+ +------+ +----+ | 94362306a36Sopenharmony_ci * | r3 | | r2 | | r1 | | 94462306a36Sopenharmony_ci * +----------+----+------+---+----+--+ 94562306a36Sopenharmony_ci * ^ ^ 94662306a36Sopenharmony_ci * | | 94762306a36Sopenharmony_ci * | max_addr 94862306a36Sopenharmony_ci * | 94962306a36Sopenharmony_ci * min_addr 95062306a36Sopenharmony_ci * 95162306a36Sopenharmony_ci * Expect to drop the lower limit and allocate memory at the beginning of the 95262306a36Sopenharmony_ci * available memory. The region counter and total size fields get updated. 95362306a36Sopenharmony_ci * Other regions are not modified. 95462306a36Sopenharmony_ci */ 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_cistatic int alloc_nid_bottom_up_reserved_no_space_check(void) 95762306a36Sopenharmony_ci{ 95862306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[2]; 95962306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[1]; 96062306a36Sopenharmony_ci struct memblock_region *rgn3 = &memblock.reserved.regions[0]; 96162306a36Sopenharmony_ci void *allocated_ptr = NULL; 96262306a36Sopenharmony_ci struct region r1, r2; 96362306a36Sopenharmony_ci phys_addr_t r3_size = SZ_256; 96462306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 96562306a36Sopenharmony_ci phys_addr_t total_size; 96662306a36Sopenharmony_ci phys_addr_t max_addr; 96762306a36Sopenharmony_ci phys_addr_t min_addr; 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci PREFIX_PUSH(); 97062306a36Sopenharmony_ci setup_memblock(); 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES * 2; 97362306a36Sopenharmony_ci r1.size = SMP_CACHE_BYTES; 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci r2.size = SZ_128; 97662306a36Sopenharmony_ci r2.base = r1.base - (r2.size + gap_size); 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 97962306a36Sopenharmony_ci min_addr = r2.base + r2.size; 98062306a36Sopenharmony_ci max_addr = r1.base; 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 98362306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(r3_size, SMP_CACHE_BYTES, 98662306a36Sopenharmony_ci min_addr, max_addr, 98762306a36Sopenharmony_ci NUMA_NO_NODE); 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 99062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_nid_test_flags); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci ASSERT_EQ(rgn3->size, r3_size); 99362306a36Sopenharmony_ci ASSERT_EQ(rgn3->base, memblock_start_of_DRAM()); 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2.size); 99662306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, r2.base); 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size); 99962306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, r1.base); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 3); 100262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci test_pass_pop(); 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci return 0; 100762306a36Sopenharmony_ci} 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci/* 101062306a36Sopenharmony_ci * A test that tries to allocate a memory region, where max_addr is 101162306a36Sopenharmony_ci * bigger than the end address of the available memory. Expect to allocate 101262306a36Sopenharmony_ci * a region that starts at the min_addr. 101362306a36Sopenharmony_ci */ 101462306a36Sopenharmony_cistatic int alloc_nid_bottom_up_cap_max_check(void) 101562306a36Sopenharmony_ci{ 101662306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 101762306a36Sopenharmony_ci void *allocated_ptr = NULL; 101862306a36Sopenharmony_ci phys_addr_t size = SZ_256; 101962306a36Sopenharmony_ci phys_addr_t min_addr; 102062306a36Sopenharmony_ci phys_addr_t max_addr; 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_ci PREFIX_PUSH(); 102362306a36Sopenharmony_ci setup_memblock(); 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM() + SZ_1K; 102662306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM() + SZ_256; 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 102962306a36Sopenharmony_ci min_addr, max_addr, 103062306a36Sopenharmony_ci NUMA_NO_NODE); 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 103362306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 103662306a36Sopenharmony_ci ASSERT_EQ(rgn->base, min_addr); 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 103962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci test_pass_pop(); 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci return 0; 104462306a36Sopenharmony_ci} 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci/* 104762306a36Sopenharmony_ci * A test that tries to allocate a memory region, where min_addr is 104862306a36Sopenharmony_ci * smaller than the start address of the available memory. Expect to allocate 104962306a36Sopenharmony_ci * a region at the beginning of the available memory. 105062306a36Sopenharmony_ci */ 105162306a36Sopenharmony_cistatic int alloc_nid_bottom_up_cap_min_check(void) 105262306a36Sopenharmony_ci{ 105362306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 105462306a36Sopenharmony_ci void *allocated_ptr = NULL; 105562306a36Sopenharmony_ci phys_addr_t size = SZ_1K; 105662306a36Sopenharmony_ci phys_addr_t min_addr; 105762306a36Sopenharmony_ci phys_addr_t max_addr; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci PREFIX_PUSH(); 106062306a36Sopenharmony_ci setup_memblock(); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 106362306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM() - SZ_256; 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 106662306a36Sopenharmony_ci min_addr, max_addr, 106762306a36Sopenharmony_ci NUMA_NO_NODE); 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 107062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 107362306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_start_of_DRAM()); 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 107662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci test_pass_pop(); 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci return 0; 108162306a36Sopenharmony_ci} 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci/* Test case wrappers for range tests */ 108462306a36Sopenharmony_cistatic int alloc_nid_simple_check(void) 108562306a36Sopenharmony_ci{ 108662306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 108762306a36Sopenharmony_ci memblock_set_bottom_up(false); 108862306a36Sopenharmony_ci alloc_nid_top_down_simple_check(); 108962306a36Sopenharmony_ci memblock_set_bottom_up(true); 109062306a36Sopenharmony_ci alloc_nid_bottom_up_simple_check(); 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_ci return 0; 109362306a36Sopenharmony_ci} 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_cistatic int alloc_nid_misaligned_check(void) 109662306a36Sopenharmony_ci{ 109762306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 109862306a36Sopenharmony_ci memblock_set_bottom_up(false); 109962306a36Sopenharmony_ci alloc_nid_top_down_end_misaligned_check(); 110062306a36Sopenharmony_ci memblock_set_bottom_up(true); 110162306a36Sopenharmony_ci alloc_nid_bottom_up_start_misaligned_check(); 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci return 0; 110462306a36Sopenharmony_ci} 110562306a36Sopenharmony_ci 110662306a36Sopenharmony_cistatic int alloc_nid_narrow_range_check(void) 110762306a36Sopenharmony_ci{ 110862306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 110962306a36Sopenharmony_ci memblock_set_bottom_up(false); 111062306a36Sopenharmony_ci alloc_nid_top_down_narrow_range_check(); 111162306a36Sopenharmony_ci memblock_set_bottom_up(true); 111262306a36Sopenharmony_ci alloc_nid_bottom_up_narrow_range_check(); 111362306a36Sopenharmony_ci 111462306a36Sopenharmony_ci return 0; 111562306a36Sopenharmony_ci} 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_cistatic int alloc_nid_reserved_with_space_check(void) 111862306a36Sopenharmony_ci{ 111962306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 112062306a36Sopenharmony_ci memblock_set_bottom_up(false); 112162306a36Sopenharmony_ci alloc_nid_top_down_reserved_with_space_check(); 112262306a36Sopenharmony_ci memblock_set_bottom_up(true); 112362306a36Sopenharmony_ci alloc_nid_bottom_up_reserved_with_space_check(); 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci return 0; 112662306a36Sopenharmony_ci} 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic int alloc_nid_reserved_no_space_check(void) 112962306a36Sopenharmony_ci{ 113062306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 113162306a36Sopenharmony_ci memblock_set_bottom_up(false); 113262306a36Sopenharmony_ci alloc_nid_top_down_reserved_no_space_check(); 113362306a36Sopenharmony_ci memblock_set_bottom_up(true); 113462306a36Sopenharmony_ci alloc_nid_bottom_up_reserved_no_space_check(); 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci return 0; 113762306a36Sopenharmony_ci} 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_cistatic int alloc_nid_cap_max_check(void) 114062306a36Sopenharmony_ci{ 114162306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 114262306a36Sopenharmony_ci memblock_set_bottom_up(false); 114362306a36Sopenharmony_ci alloc_nid_top_down_cap_max_check(); 114462306a36Sopenharmony_ci memblock_set_bottom_up(true); 114562306a36Sopenharmony_ci alloc_nid_bottom_up_cap_max_check(); 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_ci return 0; 114862306a36Sopenharmony_ci} 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_cistatic int alloc_nid_cap_min_check(void) 115162306a36Sopenharmony_ci{ 115262306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 115362306a36Sopenharmony_ci memblock_set_bottom_up(false); 115462306a36Sopenharmony_ci alloc_nid_top_down_cap_min_check(); 115562306a36Sopenharmony_ci memblock_set_bottom_up(true); 115662306a36Sopenharmony_ci alloc_nid_bottom_up_cap_min_check(); 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_ci return 0; 115962306a36Sopenharmony_ci} 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_cistatic int alloc_nid_min_reserved_check(void) 116262306a36Sopenharmony_ci{ 116362306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 116462306a36Sopenharmony_ci run_top_down(alloc_nid_min_reserved_generic_check); 116562306a36Sopenharmony_ci run_bottom_up(alloc_nid_min_reserved_generic_check); 116662306a36Sopenharmony_ci 116762306a36Sopenharmony_ci return 0; 116862306a36Sopenharmony_ci} 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_cistatic int alloc_nid_max_reserved_check(void) 117162306a36Sopenharmony_ci{ 117262306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 117362306a36Sopenharmony_ci run_top_down(alloc_nid_max_reserved_generic_check); 117462306a36Sopenharmony_ci run_bottom_up(alloc_nid_max_reserved_generic_check); 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci return 0; 117762306a36Sopenharmony_ci} 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_cistatic int alloc_nid_exact_address_check(void) 118062306a36Sopenharmony_ci{ 118162306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 118262306a36Sopenharmony_ci run_top_down(alloc_nid_exact_address_generic_check); 118362306a36Sopenharmony_ci run_bottom_up(alloc_nid_exact_address_generic_check); 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci return 0; 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_cistatic int alloc_nid_reserved_full_merge_check(void) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 119162306a36Sopenharmony_ci run_top_down(alloc_nid_reserved_full_merge_generic_check); 119262306a36Sopenharmony_ci run_bottom_up(alloc_nid_reserved_full_merge_generic_check); 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci return 0; 119562306a36Sopenharmony_ci} 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_cistatic int alloc_nid_reserved_all_check(void) 119862306a36Sopenharmony_ci{ 119962306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 120062306a36Sopenharmony_ci run_top_down(alloc_nid_reserved_all_generic_check); 120162306a36Sopenharmony_ci run_bottom_up(alloc_nid_reserved_all_generic_check); 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci return 0; 120462306a36Sopenharmony_ci} 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_cistatic int alloc_nid_low_max_check(void) 120762306a36Sopenharmony_ci{ 120862306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 120962306a36Sopenharmony_ci run_top_down(alloc_nid_low_max_generic_check); 121062306a36Sopenharmony_ci run_bottom_up(alloc_nid_low_max_generic_check); 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci return 0; 121362306a36Sopenharmony_ci} 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_cistatic int memblock_alloc_nid_range_checks(void) 121662306a36Sopenharmony_ci{ 121762306a36Sopenharmony_ci test_print("Running %s range tests...\n", 121862306a36Sopenharmony_ci get_memblock_alloc_nid_name(alloc_nid_test_flags)); 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci alloc_nid_simple_check(); 122162306a36Sopenharmony_ci alloc_nid_misaligned_check(); 122262306a36Sopenharmony_ci alloc_nid_narrow_range_check(); 122362306a36Sopenharmony_ci alloc_nid_reserved_with_space_check(); 122462306a36Sopenharmony_ci alloc_nid_reserved_no_space_check(); 122562306a36Sopenharmony_ci alloc_nid_cap_max_check(); 122662306a36Sopenharmony_ci alloc_nid_cap_min_check(); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci alloc_nid_min_reserved_check(); 122962306a36Sopenharmony_ci alloc_nid_max_reserved_check(); 123062306a36Sopenharmony_ci alloc_nid_exact_address_check(); 123162306a36Sopenharmony_ci alloc_nid_reserved_full_merge_check(); 123262306a36Sopenharmony_ci alloc_nid_reserved_all_check(); 123362306a36Sopenharmony_ci alloc_nid_low_max_check(); 123462306a36Sopenharmony_ci 123562306a36Sopenharmony_ci return 0; 123662306a36Sopenharmony_ci} 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci/* 123962306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 124062306a36Sopenharmony_ci * has enough memory to allocate a region of the requested size. 124162306a36Sopenharmony_ci * Expect to allocate an aligned region at the end of the requested node. 124262306a36Sopenharmony_ci */ 124362306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_simple_check(void) 124462306a36Sopenharmony_ci{ 124562306a36Sopenharmony_ci int nid_req = 3; 124662306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 124762306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 124862306a36Sopenharmony_ci void *allocated_ptr = NULL; 124962306a36Sopenharmony_ci phys_addr_t size; 125062306a36Sopenharmony_ci phys_addr_t min_addr; 125162306a36Sopenharmony_ci phys_addr_t max_addr; 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci PREFIX_PUSH(); 125462306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci ASSERT_LE(SZ_4, req_node->size); 125762306a36Sopenharmony_ci size = req_node->size / SZ_4; 125862306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 125962306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 126262306a36Sopenharmony_ci min_addr, max_addr, nid_req); 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 126562306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 126862306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(req_node) - size); 126962306a36Sopenharmony_ci ASSERT_LE(req_node->base, new_rgn->base); 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 127262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_ci test_pass_pop(); 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci return 0; 127762306a36Sopenharmony_ci} 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_ci/* 128062306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 128162306a36Sopenharmony_ci * does not have enough memory to allocate a region of the requested size: 128262306a36Sopenharmony_ci * 128362306a36Sopenharmony_ci * | +-----+ +------------------+ | 128462306a36Sopenharmony_ci * | | req | | expected | | 128562306a36Sopenharmony_ci * +---+-----+----------+------------------+-----+ 128662306a36Sopenharmony_ci * 128762306a36Sopenharmony_ci * | +---------+ | 128862306a36Sopenharmony_ci * | | rgn | | 128962306a36Sopenharmony_ci * +-----------------------------+---------+-----+ 129062306a36Sopenharmony_ci * 129162306a36Sopenharmony_ci * Expect to allocate an aligned region at the end of the last node that has 129262306a36Sopenharmony_ci * enough memory (in this case, nid = 6) after falling back to NUMA_NO_NODE. 129362306a36Sopenharmony_ci */ 129462306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_small_node_check(void) 129562306a36Sopenharmony_ci{ 129662306a36Sopenharmony_ci int nid_req = 1; 129762306a36Sopenharmony_ci int nid_exp = 6; 129862306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 129962306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 130062306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 130162306a36Sopenharmony_ci void *allocated_ptr = NULL; 130262306a36Sopenharmony_ci phys_addr_t size; 130362306a36Sopenharmony_ci phys_addr_t min_addr; 130462306a36Sopenharmony_ci phys_addr_t max_addr; 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci PREFIX_PUSH(); 130762306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci size = SZ_2 * req_node->size; 131062306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 131162306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 131462306a36Sopenharmony_ci min_addr, max_addr, nid_req); 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 131762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 132062306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(exp_node) - size); 132162306a36Sopenharmony_ci ASSERT_LE(exp_node->base, new_rgn->base); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 132462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci test_pass_pop(); 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci return 0; 132962306a36Sopenharmony_ci} 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci/* 133262306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 133362306a36Sopenharmony_ci * is fully reserved: 133462306a36Sopenharmony_ci * 133562306a36Sopenharmony_ci * | +---------+ +------------------+ | 133662306a36Sopenharmony_ci * | |requested| | expected | | 133762306a36Sopenharmony_ci * +--------------+---------+------------+------------------+-----+ 133862306a36Sopenharmony_ci * 133962306a36Sopenharmony_ci * | +---------+ +---------+ | 134062306a36Sopenharmony_ci * | | reserved| | new | | 134162306a36Sopenharmony_ci * +--------------+---------+---------------------+---------+-----+ 134262306a36Sopenharmony_ci * 134362306a36Sopenharmony_ci * Expect to allocate an aligned region at the end of the last node that is 134462306a36Sopenharmony_ci * large enough and has enough unreserved memory (in this case, nid = 6) after 134562306a36Sopenharmony_ci * falling back to NUMA_NO_NODE. The region count and total size get updated. 134662306a36Sopenharmony_ci */ 134762306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_node_reserved_check(void) 134862306a36Sopenharmony_ci{ 134962306a36Sopenharmony_ci int nid_req = 2; 135062306a36Sopenharmony_ci int nid_exp = 6; 135162306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[1]; 135262306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 135362306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 135462306a36Sopenharmony_ci void *allocated_ptr = NULL; 135562306a36Sopenharmony_ci phys_addr_t size; 135662306a36Sopenharmony_ci phys_addr_t min_addr; 135762306a36Sopenharmony_ci phys_addr_t max_addr; 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci PREFIX_PUSH(); 136062306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci size = req_node->size; 136362306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 136462306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci memblock_reserve(req_node->base, req_node->size); 136762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 136862306a36Sopenharmony_ci min_addr, max_addr, nid_req); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 137162306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 137462306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(exp_node) - size); 137562306a36Sopenharmony_ci ASSERT_LE(exp_node->base, new_rgn->base); 137662306a36Sopenharmony_ci 137762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 137862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size + req_node->size); 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci test_pass_pop(); 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci return 0; 138362306a36Sopenharmony_ci} 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci/* 138662306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 138762306a36Sopenharmony_ci * is partially reserved but has enough memory for the allocated region: 138862306a36Sopenharmony_ci * 138962306a36Sopenharmony_ci * | +---------------------------------------+ | 139062306a36Sopenharmony_ci * | | requested | | 139162306a36Sopenharmony_ci * +-----------+---------------------------------------+----------+ 139262306a36Sopenharmony_ci * 139362306a36Sopenharmony_ci * | +------------------+ +-----+ | 139462306a36Sopenharmony_ci * | | reserved | | new | | 139562306a36Sopenharmony_ci * +-----------+------------------+--------------+-----+----------+ 139662306a36Sopenharmony_ci * 139762306a36Sopenharmony_ci * Expect to allocate an aligned region at the end of the requested node. The 139862306a36Sopenharmony_ci * region count and total size get updated. 139962306a36Sopenharmony_ci */ 140062306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_part_reserved_check(void) 140162306a36Sopenharmony_ci{ 140262306a36Sopenharmony_ci int nid_req = 4; 140362306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[1]; 140462306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 140562306a36Sopenharmony_ci void *allocated_ptr = NULL; 140662306a36Sopenharmony_ci struct region r1; 140762306a36Sopenharmony_ci phys_addr_t size; 140862306a36Sopenharmony_ci phys_addr_t min_addr; 140962306a36Sopenharmony_ci phys_addr_t max_addr; 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci PREFIX_PUSH(); 141262306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci ASSERT_LE(SZ_8, req_node->size); 141562306a36Sopenharmony_ci r1.base = req_node->base; 141662306a36Sopenharmony_ci r1.size = req_node->size / SZ_2; 141762306a36Sopenharmony_ci size = r1.size / SZ_4; 141862306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 141962306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 142262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 142362306a36Sopenharmony_ci min_addr, max_addr, nid_req); 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 142662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 142962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(req_node) - size); 143062306a36Sopenharmony_ci ASSERT_LE(req_node->base, new_rgn->base); 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 143362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size + r1.size); 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci test_pass_pop(); 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci return 0; 143862306a36Sopenharmony_ci} 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci/* 144162306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 144262306a36Sopenharmony_ci * is partially reserved and does not have enough contiguous memory for the 144362306a36Sopenharmony_ci * allocated region: 144462306a36Sopenharmony_ci * 144562306a36Sopenharmony_ci * | +-----------------------+ +----------------------| 144662306a36Sopenharmony_ci * | | requested | | expected | 144762306a36Sopenharmony_ci * +-----------+-----------------------+---------+----------------------+ 144862306a36Sopenharmony_ci * 144962306a36Sopenharmony_ci * | +----------+ +-----------| 145062306a36Sopenharmony_ci * | | reserved | | new | 145162306a36Sopenharmony_ci * +-----------------+----------+---------------------------+-----------+ 145262306a36Sopenharmony_ci * 145362306a36Sopenharmony_ci * Expect to allocate an aligned region at the end of the last node that is 145462306a36Sopenharmony_ci * large enough and has enough unreserved memory (in this case, 145562306a36Sopenharmony_ci * nid = NUMA_NODES - 1) after falling back to NUMA_NO_NODE. The region count 145662306a36Sopenharmony_ci * and total size get updated. 145762306a36Sopenharmony_ci */ 145862306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_part_reserved_fallback_check(void) 145962306a36Sopenharmony_ci{ 146062306a36Sopenharmony_ci int nid_req = 4; 146162306a36Sopenharmony_ci int nid_exp = NUMA_NODES - 1; 146262306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[1]; 146362306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 146462306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 146562306a36Sopenharmony_ci void *allocated_ptr = NULL; 146662306a36Sopenharmony_ci struct region r1; 146762306a36Sopenharmony_ci phys_addr_t size; 146862306a36Sopenharmony_ci phys_addr_t min_addr; 146962306a36Sopenharmony_ci phys_addr_t max_addr; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci PREFIX_PUSH(); 147262306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci ASSERT_LE(SZ_4, req_node->size); 147562306a36Sopenharmony_ci size = req_node->size / SZ_2; 147662306a36Sopenharmony_ci r1.base = req_node->base + (size / SZ_2); 147762306a36Sopenharmony_ci r1.size = size; 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 148062306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 148362306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 148462306a36Sopenharmony_ci min_addr, max_addr, nid_req); 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 148762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 149062306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(exp_node) - size); 149162306a36Sopenharmony_ci ASSERT_LE(exp_node->base, new_rgn->base); 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 149462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size + r1.size); 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci test_pass_pop(); 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci return 0; 149962306a36Sopenharmony_ci} 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci/* 150262306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 150362306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the first 150462306a36Sopenharmony_ci * node is the requested node: 150562306a36Sopenharmony_ci * 150662306a36Sopenharmony_ci * min_addr 150762306a36Sopenharmony_ci * | max_addr 150862306a36Sopenharmony_ci * | | 150962306a36Sopenharmony_ci * v v 151062306a36Sopenharmony_ci * | +-----------------------+-----------+ | 151162306a36Sopenharmony_ci * | | requested | node3 | | 151262306a36Sopenharmony_ci * +-----------+-----------------------+-----------+--------------+ 151362306a36Sopenharmony_ci * + + 151462306a36Sopenharmony_ci * | +-----------+ | 151562306a36Sopenharmony_ci * | | rgn | | 151662306a36Sopenharmony_ci * +-----------------------+-----------+--------------------------+ 151762306a36Sopenharmony_ci * 151862306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region that ends at 151962306a36Sopenharmony_ci * the end of the requested node. 152062306a36Sopenharmony_ci */ 152162306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_split_range_low_check(void) 152262306a36Sopenharmony_ci{ 152362306a36Sopenharmony_ci int nid_req = 2; 152462306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 152562306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 152662306a36Sopenharmony_ci void *allocated_ptr = NULL; 152762306a36Sopenharmony_ci phys_addr_t size = SZ_512; 152862306a36Sopenharmony_ci phys_addr_t min_addr; 152962306a36Sopenharmony_ci phys_addr_t max_addr; 153062306a36Sopenharmony_ci phys_addr_t req_node_end; 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci PREFIX_PUSH(); 153362306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci req_node_end = region_end(req_node); 153662306a36Sopenharmony_ci min_addr = req_node_end - SZ_256; 153762306a36Sopenharmony_ci max_addr = min_addr + size; 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 154062306a36Sopenharmony_ci min_addr, max_addr, nid_req); 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 154362306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 154662306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, req_node_end - size); 154762306a36Sopenharmony_ci ASSERT_LE(req_node->base, new_rgn->base); 154862306a36Sopenharmony_ci 154962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 155062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci test_pass_pop(); 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_ci return 0; 155562306a36Sopenharmony_ci} 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci/* 155862306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 155962306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the second 156062306a36Sopenharmony_ci * node is the requested node: 156162306a36Sopenharmony_ci * 156262306a36Sopenharmony_ci * min_addr 156362306a36Sopenharmony_ci * | max_addr 156462306a36Sopenharmony_ci * | | 156562306a36Sopenharmony_ci * v v 156662306a36Sopenharmony_ci * | +--------------------------+---------+ | 156762306a36Sopenharmony_ci * | | expected |requested| | 156862306a36Sopenharmony_ci * +------+--------------------------+---------+----------------+ 156962306a36Sopenharmony_ci * + + 157062306a36Sopenharmony_ci * | +---------+ | 157162306a36Sopenharmony_ci * | | rgn | | 157262306a36Sopenharmony_ci * +-----------------------+---------+--------------------------+ 157362306a36Sopenharmony_ci * 157462306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region that 157562306a36Sopenharmony_ci * ends at the end of the first node that overlaps with the range. 157662306a36Sopenharmony_ci */ 157762306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_split_range_high_check(void) 157862306a36Sopenharmony_ci{ 157962306a36Sopenharmony_ci int nid_req = 3; 158062306a36Sopenharmony_ci int nid_exp = nid_req - 1; 158162306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 158262306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 158362306a36Sopenharmony_ci void *allocated_ptr = NULL; 158462306a36Sopenharmony_ci phys_addr_t size = SZ_512; 158562306a36Sopenharmony_ci phys_addr_t min_addr; 158662306a36Sopenharmony_ci phys_addr_t max_addr; 158762306a36Sopenharmony_ci phys_addr_t exp_node_end; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci PREFIX_PUSH(); 159062306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci exp_node_end = region_end(exp_node); 159362306a36Sopenharmony_ci min_addr = exp_node_end - SZ_256; 159462306a36Sopenharmony_ci max_addr = min_addr + size; 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 159762306a36Sopenharmony_ci min_addr, max_addr, nid_req); 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 160062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 160362306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, exp_node_end - size); 160462306a36Sopenharmony_ci ASSERT_LE(exp_node->base, new_rgn->base); 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 160762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci test_pass_pop(); 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci return 0; 161262306a36Sopenharmony_ci} 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci/* 161562306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 161662306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the requested 161762306a36Sopenharmony_ci * node ends before min_addr: 161862306a36Sopenharmony_ci * 161962306a36Sopenharmony_ci * min_addr 162062306a36Sopenharmony_ci * | max_addr 162162306a36Sopenharmony_ci * | | 162262306a36Sopenharmony_ci * v v 162362306a36Sopenharmony_ci * | +---------------+ +-------------+---------+ | 162462306a36Sopenharmony_ci * | | requested | | node1 | node2 | | 162562306a36Sopenharmony_ci * +----+---------------+--------+-------------+---------+----------+ 162662306a36Sopenharmony_ci * + + 162762306a36Sopenharmony_ci * | +---------+ | 162862306a36Sopenharmony_ci * | | rgn | | 162962306a36Sopenharmony_ci * +----------+---------+-------------------------------------------+ 163062306a36Sopenharmony_ci * 163162306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region that ends at 163262306a36Sopenharmony_ci * the end of the requested node. 163362306a36Sopenharmony_ci */ 163462306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_no_overlap_split_check(void) 163562306a36Sopenharmony_ci{ 163662306a36Sopenharmony_ci int nid_req = 2; 163762306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 163862306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 163962306a36Sopenharmony_ci struct memblock_region *node2 = &memblock.memory.regions[6]; 164062306a36Sopenharmony_ci void *allocated_ptr = NULL; 164162306a36Sopenharmony_ci phys_addr_t size; 164262306a36Sopenharmony_ci phys_addr_t min_addr; 164362306a36Sopenharmony_ci phys_addr_t max_addr; 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci PREFIX_PUSH(); 164662306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci size = SZ_512; 164962306a36Sopenharmony_ci min_addr = node2->base - SZ_256; 165062306a36Sopenharmony_ci max_addr = min_addr + size; 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 165362306a36Sopenharmony_ci min_addr, max_addr, nid_req); 165462306a36Sopenharmony_ci 165562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 165662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 165962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, region_end(req_node) - size); 166062306a36Sopenharmony_ci ASSERT_LE(req_node->base, new_rgn->base); 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 166362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci test_pass_pop(); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci return 0; 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci/* 167162306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range when 167262306a36Sopenharmony_ci * the requested node and the range do not overlap, and requested node ends 167362306a36Sopenharmony_ci * before min_addr. The range overlaps with multiple nodes along node 167462306a36Sopenharmony_ci * boundaries: 167562306a36Sopenharmony_ci * 167662306a36Sopenharmony_ci * min_addr 167762306a36Sopenharmony_ci * | max_addr 167862306a36Sopenharmony_ci * | | 167962306a36Sopenharmony_ci * v v 168062306a36Sopenharmony_ci * |-----------+ +----------+----...----+----------+ | 168162306a36Sopenharmony_ci * | requested | | min node | ... | max node | | 168262306a36Sopenharmony_ci * +-----------+-----------+----------+----...----+----------+------+ 168362306a36Sopenharmony_ci * + + 168462306a36Sopenharmony_ci * | +-----+ | 168562306a36Sopenharmony_ci * | | rgn | | 168662306a36Sopenharmony_ci * +---------------------------------------------------+-----+------+ 168762306a36Sopenharmony_ci * 168862306a36Sopenharmony_ci * Expect to allocate a memory region at the end of the final node in 168962306a36Sopenharmony_ci * the range after falling back to NUMA_NO_NODE. 169062306a36Sopenharmony_ci */ 169162306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_no_overlap_low_check(void) 169262306a36Sopenharmony_ci{ 169362306a36Sopenharmony_ci int nid_req = 0; 169462306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 169562306a36Sopenharmony_ci struct memblock_region *min_node = &memblock.memory.regions[2]; 169662306a36Sopenharmony_ci struct memblock_region *max_node = &memblock.memory.regions[5]; 169762306a36Sopenharmony_ci void *allocated_ptr = NULL; 169862306a36Sopenharmony_ci phys_addr_t size = SZ_64; 169962306a36Sopenharmony_ci phys_addr_t max_addr; 170062306a36Sopenharmony_ci phys_addr_t min_addr; 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci PREFIX_PUSH(); 170362306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci min_addr = min_node->base; 170662306a36Sopenharmony_ci max_addr = region_end(max_node); 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 170962306a36Sopenharmony_ci min_addr, max_addr, nid_req); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 171262306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 171562306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, max_addr - size); 171662306a36Sopenharmony_ci ASSERT_LE(max_node->base, new_rgn->base); 171762306a36Sopenharmony_ci 171862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 171962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci test_pass_pop(); 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci return 0; 172462306a36Sopenharmony_ci} 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci/* 172762306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range when 172862306a36Sopenharmony_ci * the requested node and the range do not overlap, and requested node starts 172962306a36Sopenharmony_ci * after max_addr. The range overlaps with multiple nodes along node 173062306a36Sopenharmony_ci * boundaries: 173162306a36Sopenharmony_ci * 173262306a36Sopenharmony_ci * min_addr 173362306a36Sopenharmony_ci * | max_addr 173462306a36Sopenharmony_ci * | | 173562306a36Sopenharmony_ci * v v 173662306a36Sopenharmony_ci * | +----------+----...----+----------+ +-----------+ | 173762306a36Sopenharmony_ci * | | min node | ... | max node | | requested | | 173862306a36Sopenharmony_ci * +-----+----------+----...----+----------+--------+-----------+---+ 173962306a36Sopenharmony_ci * + + 174062306a36Sopenharmony_ci * | +-----+ | 174162306a36Sopenharmony_ci * | | rgn | | 174262306a36Sopenharmony_ci * +---------------------------------+-----+------------------------+ 174362306a36Sopenharmony_ci * 174462306a36Sopenharmony_ci * Expect to allocate a memory region at the end of the final node in 174562306a36Sopenharmony_ci * the range after falling back to NUMA_NO_NODE. 174662306a36Sopenharmony_ci */ 174762306a36Sopenharmony_cistatic int alloc_nid_top_down_numa_no_overlap_high_check(void) 174862306a36Sopenharmony_ci{ 174962306a36Sopenharmony_ci int nid_req = 7; 175062306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 175162306a36Sopenharmony_ci struct memblock_region *min_node = &memblock.memory.regions[2]; 175262306a36Sopenharmony_ci struct memblock_region *max_node = &memblock.memory.regions[5]; 175362306a36Sopenharmony_ci void *allocated_ptr = NULL; 175462306a36Sopenharmony_ci phys_addr_t size = SZ_64; 175562306a36Sopenharmony_ci phys_addr_t max_addr; 175662306a36Sopenharmony_ci phys_addr_t min_addr; 175762306a36Sopenharmony_ci 175862306a36Sopenharmony_ci PREFIX_PUSH(); 175962306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ci min_addr = min_node->base; 176262306a36Sopenharmony_ci max_addr = region_end(max_node); 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 176562306a36Sopenharmony_ci min_addr, max_addr, nid_req); 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 176862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 176962306a36Sopenharmony_ci 177062306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 177162306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, max_addr - size); 177262306a36Sopenharmony_ci ASSERT_LE(max_node->base, new_rgn->base); 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 177562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ci test_pass_pop(); 177862306a36Sopenharmony_ci 177962306a36Sopenharmony_ci return 0; 178062306a36Sopenharmony_ci} 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci/* 178362306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 178462306a36Sopenharmony_ci * has enough memory to allocate a region of the requested size. 178562306a36Sopenharmony_ci * Expect to allocate an aligned region at the beginning of the requested node. 178662306a36Sopenharmony_ci */ 178762306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_simple_check(void) 178862306a36Sopenharmony_ci{ 178962306a36Sopenharmony_ci int nid_req = 3; 179062306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 179162306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 179262306a36Sopenharmony_ci void *allocated_ptr = NULL; 179362306a36Sopenharmony_ci phys_addr_t size; 179462306a36Sopenharmony_ci phys_addr_t min_addr; 179562306a36Sopenharmony_ci phys_addr_t max_addr; 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci PREFIX_PUSH(); 179862306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci ASSERT_LE(SZ_4, req_node->size); 180162306a36Sopenharmony_ci size = req_node->size / SZ_4; 180262306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 180362306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 180462306a36Sopenharmony_ci 180562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 180662306a36Sopenharmony_ci min_addr, max_addr, nid_req); 180762306a36Sopenharmony_ci 180862306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 180962306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 181062306a36Sopenharmony_ci 181162306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 181262306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, req_node->base); 181362306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(req_node)); 181462306a36Sopenharmony_ci 181562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 181662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci test_pass_pop(); 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci return 0; 182162306a36Sopenharmony_ci} 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci/* 182462306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 182562306a36Sopenharmony_ci * does not have enough memory to allocate a region of the requested size: 182662306a36Sopenharmony_ci * 182762306a36Sopenharmony_ci * |----------------------+-----+ | 182862306a36Sopenharmony_ci * | expected | req | | 182962306a36Sopenharmony_ci * +----------------------+-----+----------------+ 183062306a36Sopenharmony_ci * 183162306a36Sopenharmony_ci * |---------+ | 183262306a36Sopenharmony_ci * | rgn | | 183362306a36Sopenharmony_ci * +---------+-----------------------------------+ 183462306a36Sopenharmony_ci * 183562306a36Sopenharmony_ci * Expect to allocate an aligned region at the beginning of the first node that 183662306a36Sopenharmony_ci * has enough memory (in this case, nid = 0) after falling back to NUMA_NO_NODE. 183762306a36Sopenharmony_ci */ 183862306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_small_node_check(void) 183962306a36Sopenharmony_ci{ 184062306a36Sopenharmony_ci int nid_req = 1; 184162306a36Sopenharmony_ci int nid_exp = 0; 184262306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 184362306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 184462306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 184562306a36Sopenharmony_ci void *allocated_ptr = NULL; 184662306a36Sopenharmony_ci phys_addr_t size; 184762306a36Sopenharmony_ci phys_addr_t min_addr; 184862306a36Sopenharmony_ci phys_addr_t max_addr; 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci PREFIX_PUSH(); 185162306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci size = SZ_2 * req_node->size; 185462306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 185562306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 185862306a36Sopenharmony_ci min_addr, max_addr, nid_req); 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 186162306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 186462306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, exp_node->base); 186562306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(exp_node)); 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 186862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 186962306a36Sopenharmony_ci 187062306a36Sopenharmony_ci test_pass_pop(); 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_ci return 0; 187362306a36Sopenharmony_ci} 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_ci/* 187662306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 187762306a36Sopenharmony_ci * is fully reserved: 187862306a36Sopenharmony_ci * 187962306a36Sopenharmony_ci * |----------------------+ +-----------+ | 188062306a36Sopenharmony_ci * | expected | | requested | | 188162306a36Sopenharmony_ci * +----------------------+-----+-----------+--------------------+ 188262306a36Sopenharmony_ci * 188362306a36Sopenharmony_ci * |-----------+ +-----------+ | 188462306a36Sopenharmony_ci * | new | | reserved | | 188562306a36Sopenharmony_ci * +-----------+----------------+-----------+--------------------+ 188662306a36Sopenharmony_ci * 188762306a36Sopenharmony_ci * Expect to allocate an aligned region at the beginning of the first node that 188862306a36Sopenharmony_ci * is large enough and has enough unreserved memory (in this case, nid = 0) 188962306a36Sopenharmony_ci * after falling back to NUMA_NO_NODE. The region count and total size get 189062306a36Sopenharmony_ci * updated. 189162306a36Sopenharmony_ci */ 189262306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_node_reserved_check(void) 189362306a36Sopenharmony_ci{ 189462306a36Sopenharmony_ci int nid_req = 2; 189562306a36Sopenharmony_ci int nid_exp = 0; 189662306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 189762306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 189862306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 189962306a36Sopenharmony_ci void *allocated_ptr = NULL; 190062306a36Sopenharmony_ci phys_addr_t size; 190162306a36Sopenharmony_ci phys_addr_t min_addr; 190262306a36Sopenharmony_ci phys_addr_t max_addr; 190362306a36Sopenharmony_ci 190462306a36Sopenharmony_ci PREFIX_PUSH(); 190562306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 190662306a36Sopenharmony_ci 190762306a36Sopenharmony_ci size = req_node->size; 190862306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 190962306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_ci memblock_reserve(req_node->base, req_node->size); 191262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 191362306a36Sopenharmony_ci min_addr, max_addr, nid_req); 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 191662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 191762306a36Sopenharmony_ci 191862306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 191962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, exp_node->base); 192062306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(exp_node)); 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 192362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size + req_node->size); 192462306a36Sopenharmony_ci 192562306a36Sopenharmony_ci test_pass_pop(); 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_ci return 0; 192862306a36Sopenharmony_ci} 192962306a36Sopenharmony_ci 193062306a36Sopenharmony_ci/* 193162306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 193262306a36Sopenharmony_ci * is partially reserved but has enough memory for the allocated region: 193362306a36Sopenharmony_ci * 193462306a36Sopenharmony_ci * | +---------------------------------------+ | 193562306a36Sopenharmony_ci * | | requested | | 193662306a36Sopenharmony_ci * +-----------+---------------------------------------+---------+ 193762306a36Sopenharmony_ci * 193862306a36Sopenharmony_ci * | +------------------+-----+ | 193962306a36Sopenharmony_ci * | | reserved | new | | 194062306a36Sopenharmony_ci * +-----------+------------------+-----+------------------------+ 194162306a36Sopenharmony_ci * 194262306a36Sopenharmony_ci * Expect to allocate an aligned region in the requested node that merges with 194362306a36Sopenharmony_ci * the existing reserved region. The total size gets updated. 194462306a36Sopenharmony_ci */ 194562306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_part_reserved_check(void) 194662306a36Sopenharmony_ci{ 194762306a36Sopenharmony_ci int nid_req = 4; 194862306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 194962306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 195062306a36Sopenharmony_ci void *allocated_ptr = NULL; 195162306a36Sopenharmony_ci struct region r1; 195262306a36Sopenharmony_ci phys_addr_t size; 195362306a36Sopenharmony_ci phys_addr_t min_addr; 195462306a36Sopenharmony_ci phys_addr_t max_addr; 195562306a36Sopenharmony_ci phys_addr_t total_size; 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci PREFIX_PUSH(); 195862306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 195962306a36Sopenharmony_ci 196062306a36Sopenharmony_ci ASSERT_LE(SZ_8, req_node->size); 196162306a36Sopenharmony_ci r1.base = req_node->base; 196262306a36Sopenharmony_ci r1.size = req_node->size / SZ_2; 196362306a36Sopenharmony_ci size = r1.size / SZ_4; 196462306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 196562306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 196662306a36Sopenharmony_ci total_size = size + r1.size; 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 196962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 197062306a36Sopenharmony_ci min_addr, max_addr, nid_req); 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 197362306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 197462306a36Sopenharmony_ci 197562306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, total_size); 197662306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, req_node->base); 197762306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(req_node)); 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 198062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_ci test_pass_pop(); 198362306a36Sopenharmony_ci 198462306a36Sopenharmony_ci return 0; 198562306a36Sopenharmony_ci} 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci/* 198862306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 198962306a36Sopenharmony_ci * is partially reserved and does not have enough contiguous memory for the 199062306a36Sopenharmony_ci * allocated region: 199162306a36Sopenharmony_ci * 199262306a36Sopenharmony_ci * |----------------------+ +-----------------------+ | 199362306a36Sopenharmony_ci * | expected | | requested | | 199462306a36Sopenharmony_ci * +----------------------+-------+-----------------------+---------+ 199562306a36Sopenharmony_ci * 199662306a36Sopenharmony_ci * |-----------+ +----------+ | 199762306a36Sopenharmony_ci * | new | | reserved | | 199862306a36Sopenharmony_ci * +-----------+------------------------+----------+----------------+ 199962306a36Sopenharmony_ci * 200062306a36Sopenharmony_ci * Expect to allocate an aligned region at the beginning of the first 200162306a36Sopenharmony_ci * node that is large enough and has enough unreserved memory (in this case, 200262306a36Sopenharmony_ci * nid = 0) after falling back to NUMA_NO_NODE. The region count and total size 200362306a36Sopenharmony_ci * get updated. 200462306a36Sopenharmony_ci */ 200562306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_part_reserved_fallback_check(void) 200662306a36Sopenharmony_ci{ 200762306a36Sopenharmony_ci int nid_req = 4; 200862306a36Sopenharmony_ci int nid_exp = 0; 200962306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 201062306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 201162306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 201262306a36Sopenharmony_ci void *allocated_ptr = NULL; 201362306a36Sopenharmony_ci struct region r1; 201462306a36Sopenharmony_ci phys_addr_t size; 201562306a36Sopenharmony_ci phys_addr_t min_addr; 201662306a36Sopenharmony_ci phys_addr_t max_addr; 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_ci PREFIX_PUSH(); 201962306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_ci ASSERT_LE(SZ_4, req_node->size); 202262306a36Sopenharmony_ci size = req_node->size / SZ_2; 202362306a36Sopenharmony_ci r1.base = req_node->base + (size / SZ_2); 202462306a36Sopenharmony_ci r1.size = size; 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 202762306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 203062306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 203162306a36Sopenharmony_ci min_addr, max_addr, nid_req); 203262306a36Sopenharmony_ci 203362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 203462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 203762306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, exp_node->base); 203862306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(exp_node)); 203962306a36Sopenharmony_ci 204062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 204162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size + r1.size); 204262306a36Sopenharmony_ci 204362306a36Sopenharmony_ci test_pass_pop(); 204462306a36Sopenharmony_ci 204562306a36Sopenharmony_ci return 0; 204662306a36Sopenharmony_ci} 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_ci/* 204962306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 205062306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the first 205162306a36Sopenharmony_ci * node is the requested node: 205262306a36Sopenharmony_ci * 205362306a36Sopenharmony_ci * min_addr 205462306a36Sopenharmony_ci * | max_addr 205562306a36Sopenharmony_ci * | | 205662306a36Sopenharmony_ci * v v 205762306a36Sopenharmony_ci * | +-----------------------+-----------+ | 205862306a36Sopenharmony_ci * | | requested | node3 | | 205962306a36Sopenharmony_ci * +-----------+-----------------------+-----------+--------------+ 206062306a36Sopenharmony_ci * + + 206162306a36Sopenharmony_ci * | +-----------+ | 206262306a36Sopenharmony_ci * | | rgn | | 206362306a36Sopenharmony_ci * +-----------+-----------+--------------------------------------+ 206462306a36Sopenharmony_ci * 206562306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region at the beginning 206662306a36Sopenharmony_ci * of the requested node. 206762306a36Sopenharmony_ci */ 206862306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_split_range_low_check(void) 206962306a36Sopenharmony_ci{ 207062306a36Sopenharmony_ci int nid_req = 2; 207162306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 207262306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 207362306a36Sopenharmony_ci void *allocated_ptr = NULL; 207462306a36Sopenharmony_ci phys_addr_t size = SZ_512; 207562306a36Sopenharmony_ci phys_addr_t min_addr; 207662306a36Sopenharmony_ci phys_addr_t max_addr; 207762306a36Sopenharmony_ci phys_addr_t req_node_end; 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci PREFIX_PUSH(); 208062306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 208162306a36Sopenharmony_ci 208262306a36Sopenharmony_ci req_node_end = region_end(req_node); 208362306a36Sopenharmony_ci min_addr = req_node_end - SZ_256; 208462306a36Sopenharmony_ci max_addr = min_addr + size; 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 208762306a36Sopenharmony_ci min_addr, max_addr, nid_req); 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 209062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 209162306a36Sopenharmony_ci 209262306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 209362306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, req_node->base); 209462306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), req_node_end); 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 209762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 209862306a36Sopenharmony_ci 209962306a36Sopenharmony_ci test_pass_pop(); 210062306a36Sopenharmony_ci 210162306a36Sopenharmony_ci return 0; 210262306a36Sopenharmony_ci} 210362306a36Sopenharmony_ci 210462306a36Sopenharmony_ci/* 210562306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 210662306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the second 210762306a36Sopenharmony_ci * node is the requested node: 210862306a36Sopenharmony_ci * 210962306a36Sopenharmony_ci * min_addr 211062306a36Sopenharmony_ci * | max_addr 211162306a36Sopenharmony_ci * | | 211262306a36Sopenharmony_ci * v v 211362306a36Sopenharmony_ci * |------------------+ +----------------------+---------+ | 211462306a36Sopenharmony_ci * | expected | | previous |requested| | 211562306a36Sopenharmony_ci * +------------------+--------+----------------------+---------+------+ 211662306a36Sopenharmony_ci * + + 211762306a36Sopenharmony_ci * |---------+ | 211862306a36Sopenharmony_ci * | rgn | | 211962306a36Sopenharmony_ci * +---------+---------------------------------------------------------+ 212062306a36Sopenharmony_ci * 212162306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region at the beginning 212262306a36Sopenharmony_ci * of the first node that has enough memory. 212362306a36Sopenharmony_ci */ 212462306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_split_range_high_check(void) 212562306a36Sopenharmony_ci{ 212662306a36Sopenharmony_ci int nid_req = 3; 212762306a36Sopenharmony_ci int nid_exp = 0; 212862306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 212962306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 213062306a36Sopenharmony_ci struct memblock_region *exp_node = &memblock.memory.regions[nid_exp]; 213162306a36Sopenharmony_ci void *allocated_ptr = NULL; 213262306a36Sopenharmony_ci phys_addr_t size = SZ_512; 213362306a36Sopenharmony_ci phys_addr_t min_addr; 213462306a36Sopenharmony_ci phys_addr_t max_addr; 213562306a36Sopenharmony_ci phys_addr_t exp_node_end; 213662306a36Sopenharmony_ci 213762306a36Sopenharmony_ci PREFIX_PUSH(); 213862306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 213962306a36Sopenharmony_ci 214062306a36Sopenharmony_ci exp_node_end = region_end(req_node); 214162306a36Sopenharmony_ci min_addr = req_node->base - SZ_256; 214262306a36Sopenharmony_ci max_addr = min_addr + size; 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 214562306a36Sopenharmony_ci min_addr, max_addr, nid_req); 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 214862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 215162306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, exp_node->base); 215262306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), exp_node_end); 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 215562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 215662306a36Sopenharmony_ci 215762306a36Sopenharmony_ci test_pass_pop(); 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci return 0; 216062306a36Sopenharmony_ci} 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci/* 216362306a36Sopenharmony_ci * A test that tries to allocate a memory region that spans over the min_addr 216462306a36Sopenharmony_ci * and max_addr range and overlaps with two different nodes, where the requested 216562306a36Sopenharmony_ci * node ends before min_addr: 216662306a36Sopenharmony_ci * 216762306a36Sopenharmony_ci * min_addr 216862306a36Sopenharmony_ci * | max_addr 216962306a36Sopenharmony_ci * | | 217062306a36Sopenharmony_ci * v v 217162306a36Sopenharmony_ci * | +---------------+ +-------------+---------+ | 217262306a36Sopenharmony_ci * | | requested | | node1 | node2 | | 217362306a36Sopenharmony_ci * +----+---------------+--------+-------------+---------+---------+ 217462306a36Sopenharmony_ci * + + 217562306a36Sopenharmony_ci * | +---------+ | 217662306a36Sopenharmony_ci * | | rgn | | 217762306a36Sopenharmony_ci * +----+---------+------------------------------------------------+ 217862306a36Sopenharmony_ci * 217962306a36Sopenharmony_ci * Expect to drop the lower limit and allocate a memory region that starts at 218062306a36Sopenharmony_ci * the beginning of the requested node. 218162306a36Sopenharmony_ci */ 218262306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_no_overlap_split_check(void) 218362306a36Sopenharmony_ci{ 218462306a36Sopenharmony_ci int nid_req = 2; 218562306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 218662306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 218762306a36Sopenharmony_ci struct memblock_region *node2 = &memblock.memory.regions[6]; 218862306a36Sopenharmony_ci void *allocated_ptr = NULL; 218962306a36Sopenharmony_ci phys_addr_t size; 219062306a36Sopenharmony_ci phys_addr_t min_addr; 219162306a36Sopenharmony_ci phys_addr_t max_addr; 219262306a36Sopenharmony_ci 219362306a36Sopenharmony_ci PREFIX_PUSH(); 219462306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 219562306a36Sopenharmony_ci 219662306a36Sopenharmony_ci size = SZ_512; 219762306a36Sopenharmony_ci min_addr = node2->base - SZ_256; 219862306a36Sopenharmony_ci max_addr = min_addr + size; 219962306a36Sopenharmony_ci 220062306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 220162306a36Sopenharmony_ci min_addr, max_addr, nid_req); 220262306a36Sopenharmony_ci 220362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 220462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 220562306a36Sopenharmony_ci 220662306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 220762306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, req_node->base); 220862306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(req_node)); 220962306a36Sopenharmony_ci 221062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 221162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_ci test_pass_pop(); 221462306a36Sopenharmony_ci 221562306a36Sopenharmony_ci return 0; 221662306a36Sopenharmony_ci} 221762306a36Sopenharmony_ci 221862306a36Sopenharmony_ci/* 221962306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range when 222062306a36Sopenharmony_ci * the requested node and the range do not overlap, and requested node ends 222162306a36Sopenharmony_ci * before min_addr. The range overlaps with multiple nodes along node 222262306a36Sopenharmony_ci * boundaries: 222362306a36Sopenharmony_ci * 222462306a36Sopenharmony_ci * min_addr 222562306a36Sopenharmony_ci * | max_addr 222662306a36Sopenharmony_ci * | | 222762306a36Sopenharmony_ci * v v 222862306a36Sopenharmony_ci * |-----------+ +----------+----...----+----------+ | 222962306a36Sopenharmony_ci * | requested | | min node | ... | max node | | 223062306a36Sopenharmony_ci * +-----------+-----------+----------+----...----+----------+------+ 223162306a36Sopenharmony_ci * + + 223262306a36Sopenharmony_ci * | +-----+ | 223362306a36Sopenharmony_ci * | | rgn | | 223462306a36Sopenharmony_ci * +-----------------------+-----+----------------------------------+ 223562306a36Sopenharmony_ci * 223662306a36Sopenharmony_ci * Expect to allocate a memory region at the beginning of the first node 223762306a36Sopenharmony_ci * in the range after falling back to NUMA_NO_NODE. 223862306a36Sopenharmony_ci */ 223962306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_no_overlap_low_check(void) 224062306a36Sopenharmony_ci{ 224162306a36Sopenharmony_ci int nid_req = 0; 224262306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 224362306a36Sopenharmony_ci struct memblock_region *min_node = &memblock.memory.regions[2]; 224462306a36Sopenharmony_ci struct memblock_region *max_node = &memblock.memory.regions[5]; 224562306a36Sopenharmony_ci void *allocated_ptr = NULL; 224662306a36Sopenharmony_ci phys_addr_t size = SZ_64; 224762306a36Sopenharmony_ci phys_addr_t max_addr; 224862306a36Sopenharmony_ci phys_addr_t min_addr; 224962306a36Sopenharmony_ci 225062306a36Sopenharmony_ci PREFIX_PUSH(); 225162306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 225262306a36Sopenharmony_ci 225362306a36Sopenharmony_ci min_addr = min_node->base; 225462306a36Sopenharmony_ci max_addr = region_end(max_node); 225562306a36Sopenharmony_ci 225662306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 225762306a36Sopenharmony_ci min_addr, max_addr, nid_req); 225862306a36Sopenharmony_ci 225962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 226062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 226162306a36Sopenharmony_ci 226262306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 226362306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, min_addr); 226462306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(min_node)); 226562306a36Sopenharmony_ci 226662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 226762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_ci test_pass_pop(); 227062306a36Sopenharmony_ci 227162306a36Sopenharmony_ci return 0; 227262306a36Sopenharmony_ci} 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci/* 227562306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range when 227662306a36Sopenharmony_ci * the requested node and the range do not overlap, and requested node starts 227762306a36Sopenharmony_ci * after max_addr. The range overlaps with multiple nodes along node 227862306a36Sopenharmony_ci * boundaries: 227962306a36Sopenharmony_ci * 228062306a36Sopenharmony_ci * min_addr 228162306a36Sopenharmony_ci * | max_addr 228262306a36Sopenharmony_ci * | | 228362306a36Sopenharmony_ci * v v 228462306a36Sopenharmony_ci * | +----------+----...----+----------+ +---------+ | 228562306a36Sopenharmony_ci * | | min node | ... | max node | |requested| | 228662306a36Sopenharmony_ci * +-----+----------+----...----+----------+---------+---------+---+ 228762306a36Sopenharmony_ci * + + 228862306a36Sopenharmony_ci * | +-----+ | 228962306a36Sopenharmony_ci * | | rgn | | 229062306a36Sopenharmony_ci * +-----+-----+---------------------------------------------------+ 229162306a36Sopenharmony_ci * 229262306a36Sopenharmony_ci * Expect to allocate a memory region at the beginning of the first node 229362306a36Sopenharmony_ci * in the range after falling back to NUMA_NO_NODE. 229462306a36Sopenharmony_ci */ 229562306a36Sopenharmony_cistatic int alloc_nid_bottom_up_numa_no_overlap_high_check(void) 229662306a36Sopenharmony_ci{ 229762306a36Sopenharmony_ci int nid_req = 7; 229862306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 229962306a36Sopenharmony_ci struct memblock_region *min_node = &memblock.memory.regions[2]; 230062306a36Sopenharmony_ci struct memblock_region *max_node = &memblock.memory.regions[5]; 230162306a36Sopenharmony_ci void *allocated_ptr = NULL; 230262306a36Sopenharmony_ci phys_addr_t size = SZ_64; 230362306a36Sopenharmony_ci phys_addr_t max_addr; 230462306a36Sopenharmony_ci phys_addr_t min_addr; 230562306a36Sopenharmony_ci 230662306a36Sopenharmony_ci PREFIX_PUSH(); 230762306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci min_addr = min_node->base; 231062306a36Sopenharmony_ci max_addr = region_end(max_node); 231162306a36Sopenharmony_ci 231262306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 231362306a36Sopenharmony_ci min_addr, max_addr, nid_req); 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 231662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 231762306a36Sopenharmony_ci 231862306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, size); 231962306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, min_addr); 232062306a36Sopenharmony_ci ASSERT_LE(region_end(new_rgn), region_end(min_node)); 232162306a36Sopenharmony_ci 232262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 232362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 232462306a36Sopenharmony_ci 232562306a36Sopenharmony_ci test_pass_pop(); 232662306a36Sopenharmony_ci 232762306a36Sopenharmony_ci return 0; 232862306a36Sopenharmony_ci} 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci/* 233162306a36Sopenharmony_ci * A test that tries to allocate a memory region in a specific NUMA node that 233262306a36Sopenharmony_ci * does not have enough memory to allocate a region of the requested size. 233362306a36Sopenharmony_ci * Additionally, none of the nodes have enough memory to allocate the region: 233462306a36Sopenharmony_ci * 233562306a36Sopenharmony_ci * +-----------------------------------+ 233662306a36Sopenharmony_ci * | new | 233762306a36Sopenharmony_ci * +-----------------------------------+ 233862306a36Sopenharmony_ci * |-------+-------+-------+-------+-------+-------+-------+-------| 233962306a36Sopenharmony_ci * | node0 | node1 | node2 | node3 | node4 | node5 | node6 | node7 | 234062306a36Sopenharmony_ci * +-------+-------+-------+-------+-------+-------+-------+-------+ 234162306a36Sopenharmony_ci * 234262306a36Sopenharmony_ci * Expect no allocation to happen. 234362306a36Sopenharmony_ci */ 234462306a36Sopenharmony_cistatic int alloc_nid_numa_large_region_generic_check(void) 234562306a36Sopenharmony_ci{ 234662306a36Sopenharmony_ci int nid_req = 3; 234762306a36Sopenharmony_ci void *allocated_ptr = NULL; 234862306a36Sopenharmony_ci phys_addr_t size = MEM_SIZE / SZ_2; 234962306a36Sopenharmony_ci phys_addr_t min_addr; 235062306a36Sopenharmony_ci phys_addr_t max_addr; 235162306a36Sopenharmony_ci 235262306a36Sopenharmony_ci PREFIX_PUSH(); 235362306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 235462306a36Sopenharmony_ci 235562306a36Sopenharmony_ci min_addr = memblock_start_of_DRAM(); 235662306a36Sopenharmony_ci max_addr = memblock_end_of_DRAM(); 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 235962306a36Sopenharmony_ci min_addr, max_addr, nid_req); 236062306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 236162306a36Sopenharmony_ci 236262306a36Sopenharmony_ci test_pass_pop(); 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci return 0; 236562306a36Sopenharmony_ci} 236662306a36Sopenharmony_ci 236762306a36Sopenharmony_ci/* 236862306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_addr range when 236962306a36Sopenharmony_ci * there are two reserved regions at the borders. The requested node starts at 237062306a36Sopenharmony_ci * min_addr and ends at max_addr and is the same size as the region to be 237162306a36Sopenharmony_ci * allocated: 237262306a36Sopenharmony_ci * 237362306a36Sopenharmony_ci * min_addr 237462306a36Sopenharmony_ci * | max_addr 237562306a36Sopenharmony_ci * | | 237662306a36Sopenharmony_ci * v v 237762306a36Sopenharmony_ci * | +-----------+-----------------------+-----------------------| 237862306a36Sopenharmony_ci * | | node5 | requested | node7 | 237962306a36Sopenharmony_ci * +------+-----------+-----------------------+-----------------------+ 238062306a36Sopenharmony_ci * + + 238162306a36Sopenharmony_ci * | +----+-----------------------+----+ | 238262306a36Sopenharmony_ci * | | r2 | new | r1 | | 238362306a36Sopenharmony_ci * +-------------+----+-----------------------+----+------------------+ 238462306a36Sopenharmony_ci * 238562306a36Sopenharmony_ci * Expect to merge all of the regions into one. The region counter and total 238662306a36Sopenharmony_ci * size fields get updated. 238762306a36Sopenharmony_ci */ 238862306a36Sopenharmony_cistatic int alloc_nid_numa_reserved_full_merge_generic_check(void) 238962306a36Sopenharmony_ci{ 239062306a36Sopenharmony_ci int nid_req = 6; 239162306a36Sopenharmony_ci int nid_next = nid_req + 1; 239262306a36Sopenharmony_ci struct memblock_region *new_rgn = &memblock.reserved.regions[0]; 239362306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 239462306a36Sopenharmony_ci struct memblock_region *next_node = &memblock.memory.regions[nid_next]; 239562306a36Sopenharmony_ci void *allocated_ptr = NULL; 239662306a36Sopenharmony_ci struct region r1, r2; 239762306a36Sopenharmony_ci phys_addr_t size = req_node->size; 239862306a36Sopenharmony_ci phys_addr_t total_size; 239962306a36Sopenharmony_ci phys_addr_t max_addr; 240062306a36Sopenharmony_ci phys_addr_t min_addr; 240162306a36Sopenharmony_ci 240262306a36Sopenharmony_ci PREFIX_PUSH(); 240362306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 240462306a36Sopenharmony_ci 240562306a36Sopenharmony_ci r1.base = next_node->base; 240662306a36Sopenharmony_ci r1.size = SZ_128; 240762306a36Sopenharmony_ci 240862306a36Sopenharmony_ci r2.size = SZ_128; 240962306a36Sopenharmony_ci r2.base = r1.base - (size + r2.size); 241062306a36Sopenharmony_ci 241162306a36Sopenharmony_ci total_size = r1.size + r2.size + size; 241262306a36Sopenharmony_ci min_addr = r2.base + r2.size; 241362306a36Sopenharmony_ci max_addr = r1.base; 241462306a36Sopenharmony_ci 241562306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 241662306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 241762306a36Sopenharmony_ci 241862306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 241962306a36Sopenharmony_ci min_addr, max_addr, nid_req); 242062306a36Sopenharmony_ci 242162306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 242262306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_nid_test_flags); 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_ci ASSERT_EQ(new_rgn->size, total_size); 242562306a36Sopenharmony_ci ASSERT_EQ(new_rgn->base, r2.base); 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci ASSERT_LE(new_rgn->base, req_node->base); 242862306a36Sopenharmony_ci ASSERT_LE(region_end(req_node), region_end(new_rgn)); 242962306a36Sopenharmony_ci 243062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 243162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 243262306a36Sopenharmony_ci 243362306a36Sopenharmony_ci test_pass_pop(); 243462306a36Sopenharmony_ci 243562306a36Sopenharmony_ci return 0; 243662306a36Sopenharmony_ci} 243762306a36Sopenharmony_ci 243862306a36Sopenharmony_ci/* 243962306a36Sopenharmony_ci * A test that tries to allocate memory within min_addr and max_add range, 244062306a36Sopenharmony_ci * where the total range can fit the region, but it is split between two nodes 244162306a36Sopenharmony_ci * and everything else is reserved. Additionally, nid is set to NUMA_NO_NODE 244262306a36Sopenharmony_ci * instead of requesting a specific node: 244362306a36Sopenharmony_ci * 244462306a36Sopenharmony_ci * +-----------+ 244562306a36Sopenharmony_ci * | new | 244662306a36Sopenharmony_ci * +-----------+ 244762306a36Sopenharmony_ci * | +---------------------+-----------| 244862306a36Sopenharmony_ci * | | prev node | next node | 244962306a36Sopenharmony_ci * +------+---------------------+-----------+ 245062306a36Sopenharmony_ci * + + 245162306a36Sopenharmony_ci * |----------------------+ +-----| 245262306a36Sopenharmony_ci * | r1 | | r2 | 245362306a36Sopenharmony_ci * +----------------------+-----------+-----+ 245462306a36Sopenharmony_ci * ^ ^ 245562306a36Sopenharmony_ci * | | 245662306a36Sopenharmony_ci * | max_addr 245762306a36Sopenharmony_ci * | 245862306a36Sopenharmony_ci * min_addr 245962306a36Sopenharmony_ci * 246062306a36Sopenharmony_ci * Expect no allocation to happen. 246162306a36Sopenharmony_ci */ 246262306a36Sopenharmony_cistatic int alloc_nid_numa_split_all_reserved_generic_check(void) 246362306a36Sopenharmony_ci{ 246462306a36Sopenharmony_ci void *allocated_ptr = NULL; 246562306a36Sopenharmony_ci struct memblock_region *next_node = &memblock.memory.regions[7]; 246662306a36Sopenharmony_ci struct region r1, r2; 246762306a36Sopenharmony_ci phys_addr_t size = SZ_256; 246862306a36Sopenharmony_ci phys_addr_t max_addr; 246962306a36Sopenharmony_ci phys_addr_t min_addr; 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ci PREFIX_PUSH(); 247262306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci r2.base = next_node->base + SZ_128; 247562306a36Sopenharmony_ci r2.size = memblock_end_of_DRAM() - r2.base; 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci r1.size = MEM_SIZE - (r2.size + size); 247862306a36Sopenharmony_ci r1.base = memblock_start_of_DRAM(); 247962306a36Sopenharmony_ci 248062306a36Sopenharmony_ci min_addr = r1.base + r1.size; 248162306a36Sopenharmony_ci max_addr = r2.base; 248262306a36Sopenharmony_ci 248362306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 248462306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 248562306a36Sopenharmony_ci 248662306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES, 248762306a36Sopenharmony_ci min_addr, max_addr, 248862306a36Sopenharmony_ci NUMA_NO_NODE); 248962306a36Sopenharmony_ci 249062306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 249162306a36Sopenharmony_ci 249262306a36Sopenharmony_ci test_pass_pop(); 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci return 0; 249562306a36Sopenharmony_ci} 249662306a36Sopenharmony_ci 249762306a36Sopenharmony_ci/* 249862306a36Sopenharmony_ci * A simple test that tries to allocate a memory region through the 249962306a36Sopenharmony_ci * memblock_alloc_node() on a NUMA node with id `nid`. Expected to have the 250062306a36Sopenharmony_ci * correct NUMA node set for the new region. 250162306a36Sopenharmony_ci */ 250262306a36Sopenharmony_cistatic int alloc_node_on_correct_nid(void) 250362306a36Sopenharmony_ci{ 250462306a36Sopenharmony_ci int nid_req = 2; 250562306a36Sopenharmony_ci void *allocated_ptr = NULL; 250662306a36Sopenharmony_ci#ifdef CONFIG_NUMA 250762306a36Sopenharmony_ci struct memblock_region *req_node = &memblock.memory.regions[nid_req]; 250862306a36Sopenharmony_ci#endif 250962306a36Sopenharmony_ci phys_addr_t size = SZ_512; 251062306a36Sopenharmony_ci 251162306a36Sopenharmony_ci PREFIX_PUSH(); 251262306a36Sopenharmony_ci setup_numa_memblock(node_fractions); 251362306a36Sopenharmony_ci 251462306a36Sopenharmony_ci allocated_ptr = memblock_alloc_node(size, SMP_CACHE_BYTES, nid_req); 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 251762306a36Sopenharmony_ci#ifdef CONFIG_NUMA 251862306a36Sopenharmony_ci ASSERT_EQ(nid_req, req_node->nid); 251962306a36Sopenharmony_ci#endif 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_ci test_pass_pop(); 252262306a36Sopenharmony_ci 252362306a36Sopenharmony_ci return 0; 252462306a36Sopenharmony_ci} 252562306a36Sopenharmony_ci 252662306a36Sopenharmony_ci/* Test case wrappers for NUMA tests */ 252762306a36Sopenharmony_cistatic int alloc_nid_numa_simple_check(void) 252862306a36Sopenharmony_ci{ 252962306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 253062306a36Sopenharmony_ci memblock_set_bottom_up(false); 253162306a36Sopenharmony_ci alloc_nid_top_down_numa_simple_check(); 253262306a36Sopenharmony_ci memblock_set_bottom_up(true); 253362306a36Sopenharmony_ci alloc_nid_bottom_up_numa_simple_check(); 253462306a36Sopenharmony_ci 253562306a36Sopenharmony_ci return 0; 253662306a36Sopenharmony_ci} 253762306a36Sopenharmony_ci 253862306a36Sopenharmony_cistatic int alloc_nid_numa_small_node_check(void) 253962306a36Sopenharmony_ci{ 254062306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 254162306a36Sopenharmony_ci memblock_set_bottom_up(false); 254262306a36Sopenharmony_ci alloc_nid_top_down_numa_small_node_check(); 254362306a36Sopenharmony_ci memblock_set_bottom_up(true); 254462306a36Sopenharmony_ci alloc_nid_bottom_up_numa_small_node_check(); 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_ci return 0; 254762306a36Sopenharmony_ci} 254862306a36Sopenharmony_ci 254962306a36Sopenharmony_cistatic int alloc_nid_numa_node_reserved_check(void) 255062306a36Sopenharmony_ci{ 255162306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 255262306a36Sopenharmony_ci memblock_set_bottom_up(false); 255362306a36Sopenharmony_ci alloc_nid_top_down_numa_node_reserved_check(); 255462306a36Sopenharmony_ci memblock_set_bottom_up(true); 255562306a36Sopenharmony_ci alloc_nid_bottom_up_numa_node_reserved_check(); 255662306a36Sopenharmony_ci 255762306a36Sopenharmony_ci return 0; 255862306a36Sopenharmony_ci} 255962306a36Sopenharmony_ci 256062306a36Sopenharmony_cistatic int alloc_nid_numa_part_reserved_check(void) 256162306a36Sopenharmony_ci{ 256262306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 256362306a36Sopenharmony_ci memblock_set_bottom_up(false); 256462306a36Sopenharmony_ci alloc_nid_top_down_numa_part_reserved_check(); 256562306a36Sopenharmony_ci memblock_set_bottom_up(true); 256662306a36Sopenharmony_ci alloc_nid_bottom_up_numa_part_reserved_check(); 256762306a36Sopenharmony_ci 256862306a36Sopenharmony_ci return 0; 256962306a36Sopenharmony_ci} 257062306a36Sopenharmony_ci 257162306a36Sopenharmony_cistatic int alloc_nid_numa_part_reserved_fallback_check(void) 257262306a36Sopenharmony_ci{ 257362306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 257462306a36Sopenharmony_ci memblock_set_bottom_up(false); 257562306a36Sopenharmony_ci alloc_nid_top_down_numa_part_reserved_fallback_check(); 257662306a36Sopenharmony_ci memblock_set_bottom_up(true); 257762306a36Sopenharmony_ci alloc_nid_bottom_up_numa_part_reserved_fallback_check(); 257862306a36Sopenharmony_ci 257962306a36Sopenharmony_ci return 0; 258062306a36Sopenharmony_ci} 258162306a36Sopenharmony_ci 258262306a36Sopenharmony_cistatic int alloc_nid_numa_split_range_low_check(void) 258362306a36Sopenharmony_ci{ 258462306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 258562306a36Sopenharmony_ci memblock_set_bottom_up(false); 258662306a36Sopenharmony_ci alloc_nid_top_down_numa_split_range_low_check(); 258762306a36Sopenharmony_ci memblock_set_bottom_up(true); 258862306a36Sopenharmony_ci alloc_nid_bottom_up_numa_split_range_low_check(); 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci return 0; 259162306a36Sopenharmony_ci} 259262306a36Sopenharmony_ci 259362306a36Sopenharmony_cistatic int alloc_nid_numa_split_range_high_check(void) 259462306a36Sopenharmony_ci{ 259562306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 259662306a36Sopenharmony_ci memblock_set_bottom_up(false); 259762306a36Sopenharmony_ci alloc_nid_top_down_numa_split_range_high_check(); 259862306a36Sopenharmony_ci memblock_set_bottom_up(true); 259962306a36Sopenharmony_ci alloc_nid_bottom_up_numa_split_range_high_check(); 260062306a36Sopenharmony_ci 260162306a36Sopenharmony_ci return 0; 260262306a36Sopenharmony_ci} 260362306a36Sopenharmony_ci 260462306a36Sopenharmony_cistatic int alloc_nid_numa_no_overlap_split_check(void) 260562306a36Sopenharmony_ci{ 260662306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 260762306a36Sopenharmony_ci memblock_set_bottom_up(false); 260862306a36Sopenharmony_ci alloc_nid_top_down_numa_no_overlap_split_check(); 260962306a36Sopenharmony_ci memblock_set_bottom_up(true); 261062306a36Sopenharmony_ci alloc_nid_bottom_up_numa_no_overlap_split_check(); 261162306a36Sopenharmony_ci 261262306a36Sopenharmony_ci return 0; 261362306a36Sopenharmony_ci} 261462306a36Sopenharmony_ci 261562306a36Sopenharmony_cistatic int alloc_nid_numa_no_overlap_low_check(void) 261662306a36Sopenharmony_ci{ 261762306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 261862306a36Sopenharmony_ci memblock_set_bottom_up(false); 261962306a36Sopenharmony_ci alloc_nid_top_down_numa_no_overlap_low_check(); 262062306a36Sopenharmony_ci memblock_set_bottom_up(true); 262162306a36Sopenharmony_ci alloc_nid_bottom_up_numa_no_overlap_low_check(); 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci return 0; 262462306a36Sopenharmony_ci} 262562306a36Sopenharmony_ci 262662306a36Sopenharmony_cistatic int alloc_nid_numa_no_overlap_high_check(void) 262762306a36Sopenharmony_ci{ 262862306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 262962306a36Sopenharmony_ci memblock_set_bottom_up(false); 263062306a36Sopenharmony_ci alloc_nid_top_down_numa_no_overlap_high_check(); 263162306a36Sopenharmony_ci memblock_set_bottom_up(true); 263262306a36Sopenharmony_ci alloc_nid_bottom_up_numa_no_overlap_high_check(); 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci return 0; 263562306a36Sopenharmony_ci} 263662306a36Sopenharmony_ci 263762306a36Sopenharmony_cistatic int alloc_nid_numa_large_region_check(void) 263862306a36Sopenharmony_ci{ 263962306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 264062306a36Sopenharmony_ci run_top_down(alloc_nid_numa_large_region_generic_check); 264162306a36Sopenharmony_ci run_bottom_up(alloc_nid_numa_large_region_generic_check); 264262306a36Sopenharmony_ci 264362306a36Sopenharmony_ci return 0; 264462306a36Sopenharmony_ci} 264562306a36Sopenharmony_ci 264662306a36Sopenharmony_cistatic int alloc_nid_numa_reserved_full_merge_check(void) 264762306a36Sopenharmony_ci{ 264862306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 264962306a36Sopenharmony_ci run_top_down(alloc_nid_numa_reserved_full_merge_generic_check); 265062306a36Sopenharmony_ci run_bottom_up(alloc_nid_numa_reserved_full_merge_generic_check); 265162306a36Sopenharmony_ci 265262306a36Sopenharmony_ci return 0; 265362306a36Sopenharmony_ci} 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_cistatic int alloc_nid_numa_split_all_reserved_check(void) 265662306a36Sopenharmony_ci{ 265762306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 265862306a36Sopenharmony_ci run_top_down(alloc_nid_numa_split_all_reserved_generic_check); 265962306a36Sopenharmony_ci run_bottom_up(alloc_nid_numa_split_all_reserved_generic_check); 266062306a36Sopenharmony_ci 266162306a36Sopenharmony_ci return 0; 266262306a36Sopenharmony_ci} 266362306a36Sopenharmony_ci 266462306a36Sopenharmony_cistatic int alloc_node_numa_on_correct_nid(void) 266562306a36Sopenharmony_ci{ 266662306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 266762306a36Sopenharmony_ci run_top_down(alloc_node_on_correct_nid); 266862306a36Sopenharmony_ci run_bottom_up(alloc_node_on_correct_nid); 266962306a36Sopenharmony_ci 267062306a36Sopenharmony_ci return 0; 267162306a36Sopenharmony_ci} 267262306a36Sopenharmony_ci 267362306a36Sopenharmony_ciint __memblock_alloc_nid_numa_checks(void) 267462306a36Sopenharmony_ci{ 267562306a36Sopenharmony_ci test_print("Running %s NUMA tests...\n", 267662306a36Sopenharmony_ci get_memblock_alloc_nid_name(alloc_nid_test_flags)); 267762306a36Sopenharmony_ci 267862306a36Sopenharmony_ci alloc_nid_numa_simple_check(); 267962306a36Sopenharmony_ci alloc_nid_numa_small_node_check(); 268062306a36Sopenharmony_ci alloc_nid_numa_node_reserved_check(); 268162306a36Sopenharmony_ci alloc_nid_numa_part_reserved_check(); 268262306a36Sopenharmony_ci alloc_nid_numa_part_reserved_fallback_check(); 268362306a36Sopenharmony_ci alloc_nid_numa_split_range_low_check(); 268462306a36Sopenharmony_ci alloc_nid_numa_split_range_high_check(); 268562306a36Sopenharmony_ci 268662306a36Sopenharmony_ci alloc_nid_numa_no_overlap_split_check(); 268762306a36Sopenharmony_ci alloc_nid_numa_no_overlap_low_check(); 268862306a36Sopenharmony_ci alloc_nid_numa_no_overlap_high_check(); 268962306a36Sopenharmony_ci alloc_nid_numa_large_region_check(); 269062306a36Sopenharmony_ci alloc_nid_numa_reserved_full_merge_check(); 269162306a36Sopenharmony_ci alloc_nid_numa_split_all_reserved_check(); 269262306a36Sopenharmony_ci 269362306a36Sopenharmony_ci alloc_node_numa_on_correct_nid(); 269462306a36Sopenharmony_ci 269562306a36Sopenharmony_ci return 0; 269662306a36Sopenharmony_ci} 269762306a36Sopenharmony_ci 269862306a36Sopenharmony_cistatic int memblock_alloc_nid_checks_internal(int flags) 269962306a36Sopenharmony_ci{ 270062306a36Sopenharmony_ci alloc_nid_test_flags = flags; 270162306a36Sopenharmony_ci 270262306a36Sopenharmony_ci prefix_reset(); 270362306a36Sopenharmony_ci prefix_push(get_memblock_alloc_nid_name(flags)); 270462306a36Sopenharmony_ci 270562306a36Sopenharmony_ci reset_memblock_attributes(); 270662306a36Sopenharmony_ci dummy_physical_memory_init(); 270762306a36Sopenharmony_ci 270862306a36Sopenharmony_ci memblock_alloc_nid_range_checks(); 270962306a36Sopenharmony_ci memblock_alloc_nid_numa_checks(); 271062306a36Sopenharmony_ci 271162306a36Sopenharmony_ci dummy_physical_memory_cleanup(); 271262306a36Sopenharmony_ci 271362306a36Sopenharmony_ci prefix_pop(); 271462306a36Sopenharmony_ci 271562306a36Sopenharmony_ci return 0; 271662306a36Sopenharmony_ci} 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ciint memblock_alloc_nid_checks(void) 271962306a36Sopenharmony_ci{ 272062306a36Sopenharmony_ci memblock_alloc_nid_checks_internal(TEST_F_NONE); 272162306a36Sopenharmony_ci memblock_alloc_nid_checks_internal(TEST_F_RAW); 272262306a36Sopenharmony_ci 272362306a36Sopenharmony_ci return 0; 272462306a36Sopenharmony_ci} 272562306a36Sopenharmony_ci 272662306a36Sopenharmony_ciint memblock_alloc_exact_nid_range_checks(void) 272762306a36Sopenharmony_ci{ 272862306a36Sopenharmony_ci alloc_nid_test_flags = (TEST_F_RAW | TEST_F_EXACT); 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci memblock_alloc_nid_range_checks(); 273162306a36Sopenharmony_ci 273262306a36Sopenharmony_ci return 0; 273362306a36Sopenharmony_ci} 2734