Fundamentals 41 min read

How Linux’s Slab Allocator Manages Memory: Deep Dive into Fast and Slow Paths

This article dissects the Linux kernel’s slab allocator, explaining its complete architecture, the fast‑path allocation from per‑CPU caches, the slow‑path mechanisms involving partial lists, NUMA node caches, and fallback to the buddy system, while detailing object initialization and freelist construction.

Bin's Tech Cabin
Bin's Tech Cabin
Bin's Tech Cabin
How Linux’s Slab Allocator Manages Memory: Deep Dive into Fast and Slow Paths

Building on the previous article that introduced the slab cache architecture, this piece examines the Linux kernel’s slab allocator in depth, covering how memory is allocated, the fast‑path and slow‑path mechanisms, and the initialization of slab objects and freelists.

1. How slab cache allocates memory

When a process is created with fork(), the kernel allocates a task_struct from its dedicated slab cache task_struct_cachep. The function dup_task_struct in /kernel/fork.c obtains a task_struct via alloc_task_struct_node, which ultimately calls kmem_cache_alloc_node to request an object from a specific NUMA node.

static struct task_struct *dup_task_struct(struct task_struct *orig, int node) {
    struct task_struct *tsk;
    // Allocate from task_struct's slab cache
    tsk = alloc_task_struct_node(node);
    ...
}

static inline struct task_struct *alloc_task_struct_node(int node) {
    return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node);
}
kmem_cache_alloc_node

forwards the request to slab_alloc_node, which first tries the per‑CPU cache.

void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) {
    return slab_alloc_node(s, gfpflags, node, _RET_IP_);
}

2. Fast allocation path

The fast path attempts to obtain an object from the CPU‑local cache kmem_cache_cpu->freelist. It verifies that the cache belongs to the current CPU, handling preemption by looping until the tid fields match. If a free object exists, it is taken directly, the freelist pointer is updated, and the allocation statistics are recorded as a fast‑path allocation.

3. Slow allocation path

If the per‑CPU cache is empty or the slab resides on a different NUMA node, the allocator falls back to the slow path.

3.1 From local CPU partial list

The kernel checks the per‑CPU partial list for a slab with free objects. If found, the slab is promoted to the CPU‑local cache and allocation proceeds.

if (slub_percpu_partial(c)) {
    page = c->page = slub_percpu_partial(c);
    slub_set_percpu_partial(c, page);
    stat(s, CPU_PARTIAL_ALLOC);
    goto redo;
}

3.2 From NUMA node cache

The allocator selects the requested NUMA node; if it lacks free memory, it chooses the nearest node. It then scans the node’s partial list, moving slabs to the CPU‑local cache or filling the partial list until a threshold is reached.

object = get_partial_node(s, get_node(s, searchnode), c, flags);
if (!object) object = get_any_partial(s, flags, c);

If no suitable slab exists in the node caches, the allocator proceeds to the buddy system.

3.3 From the buddy system

When all caches are exhausted, new_slab requests a new slab from the buddy allocator using the order defined in kmem_cache->oo. If allocation fails, the allocator falls back to the minimal size kmem_cache->min. After successful allocation, the slab’s struct page fields are initialized, the memory is poisoned for KASAN, and the freelist is built.

static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) {
    return allocate_slab(s, flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
}

4. Initializing the slab freelist

The freelist can be built sequentially or randomly (when CONFIG_SLAB_FREELIST_RANDOM is enabled). Sequential initialization starts with the first object, linking each object's freepointer to the next one. Random initialization selects objects in a random order, making the freelist unpredictable.

static bool shuffle_freelist(struct kmem_cache *s, struct page *page) {
    if (page->objects < 2 || !s->random_seq)
        return false;
    // Randomly link objects
    ...
    return true;
}

5. Slab object initialization

Each object is prepared by setup_object, which may add red zones, poison bytes, and invoke a constructor if defined. Red zones (filled with 0xbb) guard against out‑of‑bounds accesses, while poison values ( 0x6b and 0xa5) help detect use‑after‑free bugs.

static void init_object(struct kmem_cache *s, void *object, u8 val) {
    u8 *p = object;
    if (s->flags & SLAB_RED_ZONE)
        memset(p - s->red_left_pad, val, s->red_left_pad);
    if (s->flags & __OBJECT_POISON) {
        memset(p, POISON_FREE, s->object_size - 1);
        p[s->object_size - 1] = POISON_END;
    }
    if (s->flags & SLAB_RED_ZONE)
        memset(p + s->object_size, val, s->inuse - s->object_size);
}

Summary

The slab allocator follows a two‑tiered strategy: a fast path that serves allocations from per‑CPU caches, and a slow path that falls back to partial lists, NUMA node caches, and finally the buddy system. Throughout the process, the kernel carefully initializes objects, adds protective red zones, and optionally randomizes freelist order to improve security.

slab cache architecture diagram
slab cache architecture diagram
allocation flowchart
allocation flowchart
slab_alloc_node
slab_alloc_node
fast path
fast path
partial list
partial list
NUMA node allocation
NUMA node allocation
buddy system allocation
buddy system allocation
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

memory-managementLinuxNUMA
Bin's Tech Cabin
Written by

Bin's Tech Cabin

Original articles dissecting source code and sharing personal tech insights. A modest space for serious discussion, free from noise and bureaucracy.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.