Memory Allocation in Kernel space
- coolrrsh
- Aug 28, 2023
- 2 min read
Updated: Aug 29, 2023

The binary buddy allocator has a problem of internal fragmentation. It is because if kernel requests 300 bytes of data. Then the whole page frame is allocated to fit that
data. So remaining data ie. 4K - 300 becomes useless.

The Slab allocator fulfills the above requirement. The slab allocator packs commonly
allocated objects into the blocks.
There are 2 ways slab cache is allocated:-
1. KMEM_CACHE: KMEM_CACHE is a macro used to define and declare a slab cache in the Linux kernel. A slab cache is a memory management technique that helps improve memory allocation efficiency by grouping objects of the same size together. This helps to reduce memory fragmentation and improves memory allocation speed.
Slab caches are commonly used for managing frequently allocated and deallocated objects, such as kernel data structures. The KMEM_CACHE macro is used to create a slab cache with a given name, object size, and optional flags.
Example: KMEM_CACHE(my_object_cache, struct my_struct, SLAB_PANIC);
In this example, my_object_cache is the name of the cache, struct my_struct is the object type, and SLAB_PANIC is an optional flag.

2. kmem_cache_create: kmem_cache_create is a function that creates a slab cache dynamically at runtime. It's more flexible than using the KMEM_CACHE macro because it allows you to specify various parameters for the cache, such as the size of the objects, flags, constructor, and destructor functions.
Example: kmem_cache_create("my_object_cache", sizeof(struct my_struct), 0, SLAB_PANIC, NULL);
In this example, my_object_cache is the name of the cache, sizeof(struct my_struct) specifies the object size, 0 is the offset within the object, SLAB_PANIC is the cache flag, and NULL specifies no constructor function.
The choice between using KMEM_CACHE and kmem_cache_create depends on your specific use case and requirements. If you know the cache parameters at compile time and want to define a cache statically, you can use the KMEM_CACHE macro. If you need more runtime flexibility or want to dynamically create caches, then kmem_cache_create is more suitable.

Slab allocator types :-
1. SLOB
Oldest allocator. It is very compact but not performant. Mostly useful in embedded systems.
2. SLAB
It is cache efficient, good performant but it has some problems such as it wastes lot of memory and not compact like SLOB. It also waste the CPU cycles.
3. SLUB
Current default allocator, useful for large system.
SLUB Allocator in detail :-

As shown above, kmem_cache maintains two tables kmem_cache_cpu and kmem_cache_node. The block of memory are allocated per cpu by kmem_cache_cpu. The kem_cache_cpu table conatains 2 pointers (*freelist and *page) .The *freelist points to the free block of memory and *page pointer points to the beginning of slab. Note that all the blocks in slab are equal in size. When the slab is fully occupied with blocks then the *freelist points to NULL.
The table kmem_cache_node on the other hand maintains two pointers *partial and *full.
When the slab allocated in table kmem_cache_cpu gets full then the slab is pointed by the *full pointer in kmem_cache_node table. When some block gets freed from the slab pointer by this *full pointer then it moved to be pointed by *partial pointer. When some new block of data is to be added then this slab maintained by *partial pointer is used.
In this way the slub works to manage the cache memory and gives better performance.
Comments