mm/vmalloc.c

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

File Facts

System
Linux kernel
Corpus path
mm/vmalloc.c
Extension
.c
Size
147687 bytes
Lines
5571
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

module_init(proc_vmalloc_init);

#endif

static void __init vmap_init_free_space(void)
{
	unsigned long vmap_start = 1;
	const unsigned long vmap_end = ULONG_MAX;
	struct vmap_area *free;
	struct vm_struct *busy;

	/*
	 *     B     F     B     B     B     F
	 * -|-----|.....|-----|-----|-----|.....|-
	 *  |           The KVA space           |
	 *  |<--------------------------------->|
	 */
	for (busy = vmlist; busy; busy = busy->next) {
		if ((unsigned long) busy->addr - vmap_start > 0) {
			free = kmem_cache_zalloc(vmap_area_cachep, GFP_NOWAIT);
			if (!WARN_ON_ONCE(!free)) {
				free->va_start = vmap_start;
				free->va_end = (unsigned long) busy->addr;

				insert_vmap_area_augment(free, NULL,
					&free_vmap_area_root,
						&free_vmap_area_list);
			}
		}

		vmap_start = (unsigned long) busy->addr + busy->size;
	}

	if (vmap_end - vmap_start > 0) {
		free = kmem_cache_zalloc(vmap_area_cachep, GFP_NOWAIT);
		if (!WARN_ON_ONCE(!free)) {
			free->va_start = vmap_start;
			free->va_end = vmap_end;

			insert_vmap_area_augment(free, NULL,
				&free_vmap_area_root,
					&free_vmap_area_list);
		}
	}
}

static void vmap_init_nodes(void)
{
	struct vmap_node *vn;
	int i;

#if BITS_PER_LONG == 64
	/*
	 * A high threshold of max nodes is fixed and bound to 128,
	 * thus a scale factor is 1 for systems where number of cores
	 * are less or equal to specified threshold.
	 *
	 * As for NUMA-aware notes. For bigger systems, for example
	 * NUMA with multi-sockets, where we can end-up with thousands
	 * of cores in total, a "sub-numa-clustering" should be added.
	 *
	 * In this case a NUMA domain is considered as a single entity
	 * with dedicated sub-nodes in it which describe one group or
	 * set of cores. Therefore a per-domain purging is supposed to
	 * be added as well as a per-domain balancing.
	 */
	int n = clamp_t(unsigned int, num_possible_cpus(), 1, 128);

	if (n > 1) {
		vn = kmalloc_objs(*vn, n, GFP_NOWAIT);
		if (vn) {
			/* Node partition is 16 pages. */
			vmap_zone_size = (1 << 4) * PAGE_SIZE;
			nr_vmap_nodes = n;
			vmap_nodes = vn;
		} else {
			pr_err("Failed to allocate an array. Disable a node layer\n");
		}
	}
#endif

	for_each_vmap_node(vn) {
		vn->busy.root = RB_ROOT;
		INIT_LIST_HEAD(&vn->busy.head);
		spin_lock_init(&vn->busy.lock);

		vn->lazy.root = RB_ROOT;
		INIT_LIST_HEAD(&vn->lazy.head);
		spin_lock_init(&vn->lazy.lock);

Annotation

Implementation Notes