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