mm/memblock.c

Source file repositories/reference/linux-study-clean/mm/memblock.c

File Facts

System
Linux kernel
Corpus path
mm/memblock.c
Extension
.c
Size
80912 bytes
Lines
2899
Domain
Core OS
Bucket
Memory Management
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct reserve_mem_table {
	char			name[RESERVE_MEM_NAME_SIZE];
	phys_addr_t		start;
	phys_addr_t		size;
};
static struct reserve_mem_table reserved_mem_table[RESERVE_MEM_MAX_ENTRIES];
static int reserved_mem_count;
static DEFINE_MUTEX(reserve_mem_lock);

/* Add wildcard region with a lookup name */
static void __init reserved_mem_add(phys_addr_t start, phys_addr_t size,
				   const char *name)
{
	struct reserve_mem_table *map;

	map = &reserved_mem_table[reserved_mem_count++];
	map->start = start;
	map->size = size;
	strscpy(map->name, name);
}

static struct reserve_mem_table *reserve_mem_find_by_name_nolock(const char *name)
{
	struct reserve_mem_table *map;
	int i;

	for (i = 0; i < reserved_mem_count; i++) {
		map = &reserved_mem_table[i];
		if (!map->size)
			continue;
		if (strcmp(name, map->name) == 0)
			return map;
	}
	return NULL;
}

/**
 * reserve_mem_find_by_name - Find reserved memory region with a given name
 * @name: The name that is attached to a reserved memory region
 * @start: If found, holds the start address
 * @size: If found, holds the size of the address.
 *
 * @start and @size are only updated if @name is found.
 *
 * Returns: 1 if found or 0 if not found.
 */
int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size)
{
	struct reserve_mem_table *map;

	guard(mutex)(&reserve_mem_lock);
	map = reserve_mem_find_by_name_nolock(name);
	if (!map)
		return 0;

	*start = map->start;
	*size = map->size;
	return 1;
}
EXPORT_SYMBOL_GPL(reserve_mem_find_by_name);

/**
 * reserve_mem_release_by_name - Release reserved memory region with a given name
 * @name: The name that is attached to a reserved memory region
 *
 * Forcibly release the pages in the reserved memory region so that those memory
 * can be used as free memory. After released the reserved region size becomes 0.
 *
 * Returns: 1 if released or 0 if not found.
 */
int reserve_mem_release_by_name(const char *name)
{
	char buf[RESERVE_MEM_NAME_SIZE + 12];
	struct reserve_mem_table *map;
	void *start, *end;

	guard(mutex)(&reserve_mem_lock);
	map = reserve_mem_find_by_name_nolock(name);
	if (!map)
		return 0;

	start = phys_to_virt(map->start);
	end = start + map->size;
	snprintf(buf, sizeof(buf), "reserve_mem:%s", name);
	free_reserved_area(start, end, 0, buf);
	map->size = 0;

	return 1;
}

Annotation

Implementation Notes