Allocating physical memory: the buddy allocator (orders, zones, compaction), slab/SLUB object caches, kmalloc vs vmalloc (contiguity & DMA), GFP flags (GFP_KERNEL vs GFP_ATOMIC), and pressure handling — watermarks, kswapd vs direct reclaim, overcommit, and the OOM killer.
How the kernel allocates physical memory to itself and to processes — the allocators, the flags that decide how you can allocate, and what happens under pressure. Original, interview-focused notes; builds on Memory Addressing.
Two layers: the buddy allocator hands out physical page frames in power-of-two blocks; the slab/slub allocator carves those pages into small kernel objects. Which one you hit depends on whether you callalloc_pages,kmalloc, orvmalloc.
Most kernel allocations are tiny and frequent (dentries, inodes, task_structs). Handing out whole pages would waste
memory, so the slab allocator (SLUB is the modern default) keeps per-type caches of pre-carved
objects on top of buddy pages — fast alloc/free, low fragmentation, cache-friendly. Inspect with slabtop
/ /proc/slabinfo. (This is SReclaimable/SUnreclaim in
/proc/meminfo.)
kmalloc | vmalloc | |
|---|---|---|
| Backed by | Slab → buddy | Non-contiguous pages mapped contiguously in kernel VA |
| Physically contiguous? | Yes | No (virtually contiguous only) |
| Size | Small | Large |
| For | Most allocations; DMA needs contiguous | Big buffers where phys-contiguity doesn't matter |
DMA-capable hardware usually needs physically contiguous memory → kmalloc /
dma_alloc_coherent, not vmalloc.
GFP_KERNEL — normal; may sleep (reclaim/compact to satisfy the
request). The default in process context.GFP_ATOMIC — must not sleep: for interrupt/softirq context or
while holding a spinlock. Draws from emergency reserves and can fail — always check the return.GFP_NOWAIT, GFP_NOIO/GFP_NOFS (avoid recursion into I/O/FS during reclaim),
__GFP_ZERO, GFP_DMA.Picking the right flag is a real interview signal: "allocating in an interrupt handler? — GFP_ATOMIC,
and handle failure."
oom_score (tunable via oom_score_adj) and kills it — a last resort, visible in
dmesg.Committed_AS vs
CommitLimit), betting not all is touched — which is why the OOM killer exists at all.kmalloc vs vmalloc — contiguity, size, and when DMA forces the choice.GFP_KERNEL vs GFP_ATOMIC — which can sleep, and when must you use ATOMIC?