tools/testing/memblock/tests/alloc_nid_api.c

Source file repositories/reference/linux-study-clean/tools/testing/memblock/tests/alloc_nid_api.c

File Facts

System
Linux kernel
Corpus path
tools/testing/memblock/tests/alloc_nid_api.c
Extension
.c
Size
80875 bytes
Lines
2734
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
#include "alloc_nid_api.h"

static int alloc_nid_test_flags = TEST_F_NONE;

/*
 * contains the fraction of MEM_SIZE contained in each node in basis point
 * units (one hundredth of 1% or 1/10000)
 */
static const unsigned int node_fractions[] = {
	2500, /* 1/4  */
	 625, /* 1/16 */
	1250, /* 1/8  */
	1250, /* 1/8  */
	 625, /* 1/16 */
	 625, /* 1/16 */
	2500, /* 1/4  */
	 625, /* 1/16 */
};

static inline const char * const get_memblock_alloc_nid_name(int flags)
{
	if (flags & TEST_F_EXACT)
		return "memblock_alloc_exact_nid_raw";
	if (flags & TEST_F_RAW)
		return "memblock_alloc_try_nid_raw";
	return "memblock_alloc_try_nid";
}

static inline void *run_memblock_alloc_nid(phys_addr_t size,
					   phys_addr_t align,
					   phys_addr_t min_addr,
					   phys_addr_t max_addr, int nid)
{
	assert(!(alloc_nid_test_flags & TEST_F_EXACT) ||
	       (alloc_nid_test_flags & TEST_F_RAW));
	/*
	 * TEST_F_EXACT should be checked before TEST_F_RAW since
	 * memblock_alloc_exact_nid_raw() performs raw allocations.
	 */
	if (alloc_nid_test_flags & TEST_F_EXACT)
		return memblock_alloc_exact_nid_raw(size, align, min_addr,
						    max_addr, nid);
	if (alloc_nid_test_flags & TEST_F_RAW)
		return memblock_alloc_try_nid_raw(size, align, min_addr,
						  max_addr, nid);
	return memblock_alloc_try_nid(size, align, min_addr, max_addr, nid);
}

/*
 * A simple test that tries to allocate a memory region within min_addr and
 * max_addr range:
 *
 *        +                   +
 *   |    +       +-----------+      |
 *   |    |       |    rgn    |      |
 *   +----+-------+-----------+------+
 *        ^                   ^
 *        |                   |
 *        min_addr           max_addr
 *
 * Expect to allocate a region that ends at max_addr.
 */
static int alloc_nid_top_down_simple_check(void)
{
	struct memblock_region *rgn = &memblock.reserved.regions[0];
	void *allocated_ptr = NULL;
	phys_addr_t size = SZ_128;
	phys_addr_t min_addr;
	phys_addr_t max_addr;
	phys_addr_t rgn_end;

	PREFIX_PUSH();
	setup_memblock();

	min_addr = memblock_start_of_DRAM() + SMP_CACHE_BYTES * 2;
	max_addr = min_addr + SZ_512;

	allocated_ptr = run_memblock_alloc_nid(size, SMP_CACHE_BYTES,
					       min_addr, max_addr,
					       NUMA_NO_NODE);
	rgn_end = rgn->base + rgn->size;

	ASSERT_NE(allocated_ptr, NULL);
	assert_mem_content(allocated_ptr, size, alloc_nid_test_flags);

	ASSERT_EQ(rgn->size, size);
	ASSERT_EQ(rgn->base, max_addr - size);
	ASSERT_EQ(rgn_end, max_addr);

Annotation

Implementation Notes