Suppose a network packet arrives while the CPU is handling an interrupt. The kernel needs a small object to record the event.
In normal process context, memory allocation can sometimes wait. An interrupt handler cannot block and resume later, so it must allocate from memory that is immediately available or use a fallback such as dropping, deferring, or reusing work.
This is why kernel memory allocation is more complex than a simple malloc().
The kernel allocates everything from tiny objects to large I/O buffers, under very different constraints. Some callers may sleep; others cannot. Some need physically contiguous memory, while others only need a contiguous virtual range. Hardware may also impose address restrictions.
Kernel allocation depends not only on size, but also on execution context, memory layout, lifetime, locality, and the ability to make forward progress.
Linux therefore uses several specialized allocators rather than one universal allocation mechanism.
This chapter compares Linux page, buddy, slab, kmalloc, vmalloc, DMA, and memory-pool allocation, explaining how context flags, contiguity, locality, reclaim, lifetime, and forward-progress requirements determine the correct interface.