Kernel Heap

Rotary provides a kernel heap implementation that allows for quick and efficient dynamic memory allocation. The kernel heap is implemented through use of a slab allocator. It is appropriate for use in the majority of kernel components that do not have special requirements for the memory regions allocated to them.

The slab allocator pre-allocates memory in caches of fixed-size objects. Each cache consists of one or more slabs, which are blocks of contiguous pages. For example, a cache for 128-byte objects may contain multiple slabs, each holding several such objects.

Slab allocation is efficient because it reduces external fragmentation by (re)using pre-allocated, fixed-size objects, eliminating the overhead of frequent allocations and de-allocations.

Pages for slabs are allocated directly from the page frame buddy allocator via page_alloc().

The slab allocator serves as the backing allocator for kmalloc(), which provides kernel heap functionality. kmalloc() maintains slab caches for common sizes (e.g., 32, 64, and 128 bytes). If a requested size does not match an existing cache, kmalloc() selects the smallest cache that can accommodate the request.

Example Usage

Allocation and de-allocation from the heap is simple, and can be done as follows:

/* Allocate 1024 bytes of memory from the kernel heap */
void * alloc = kmalloc(1024);

/* Check the allocation succeeded */
if(!alloc) {
    klog("kmalloc() failed!\n");
    return;
}

/* Free the allocated memory */
kfree(alloc);

Relevant Source