tools/testing/memblock/tests/alloc_api.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/memblock/tests/alloc_api.c
Extension
.c
Size
22397 bytes
Lines
885
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_api.h"

static int alloc_test_flags = TEST_F_NONE;

static inline const char * const get_memblock_alloc_name(int flags)
{
	if (flags & TEST_F_RAW)
		return "memblock_alloc_raw";
	return "memblock_alloc";
}

static inline void *run_memblock_alloc(phys_addr_t size, phys_addr_t align)
{
	if (alloc_test_flags & TEST_F_RAW)
		return memblock_alloc_raw(size, align);
	return memblock_alloc(size, align);
}

/*
 * A simple test that tries to allocate a small memory region.
 * Expect to allocate an aligned region near the end of the available memory.
 */
static int alloc_top_down_simple_check(void)
{
	struct memblock_region *rgn = &memblock.reserved.regions[0];
	void *allocated_ptr = NULL;
	phys_addr_t size = SZ_2;
	phys_addr_t expected_start;

	PREFIX_PUSH();
	setup_memblock();

	expected_start = memblock_end_of_DRAM() - SMP_CACHE_BYTES;

	allocated_ptr = run_memblock_alloc(size, SMP_CACHE_BYTES);

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

	ASSERT_EQ(rgn->size, size);
	ASSERT_EQ(rgn->base, expected_start);

	ASSERT_EQ(memblock.reserved.cnt, 1);
	ASSERT_EQ(memblock.reserved.total_size, size);

	test_pass_pop();

	return 0;
}

/*
 * A test that tries to allocate memory next to a reserved region that starts at
 * the misaligned address. Expect to create two separate entries, with the new
 * entry aligned to the provided alignment:
 *
 *              +
 * |            +--------+         +--------|
 * |            |  rgn2  |         |  rgn1  |
 * +------------+--------+---------+--------+
 *              ^
 *              |
 *              Aligned address boundary
 *
 * The allocation direction is top-down and region arrays are sorted from lower
 * to higher addresses, so the new region will be the first entry in
 * memory.reserved array. The previously reserved region does not get modified.
 * Region counter and total size get updated.
 */
static int alloc_top_down_disjoint_check(void)
{
	/* After allocation, this will point to the "old" region */
	struct memblock_region *rgn1 = &memblock.reserved.regions[1];
	struct memblock_region *rgn2 = &memblock.reserved.regions[0];
	struct region r1;
	void *allocated_ptr = NULL;
	phys_addr_t r2_size = SZ_16;
	/* Use custom alignment */
	phys_addr_t alignment = SMP_CACHE_BYTES * 2;
	phys_addr_t total_size;
	phys_addr_t expected_start;

	PREFIX_PUSH();
	setup_memblock();

	r1.base = memblock_end_of_DRAM() - SZ_2;
	r1.size = SZ_2;

	total_size = r1.size + r2_size;
	expected_start = memblock_end_of_DRAM() - alignment;

Annotation

Implementation Notes