Kernel Memory Allocation¶
Purpose¶
Linux kernel drivers use dynamic memory allocation to manage driver-private data, runtime buffers, lookup tables, and temporary objects.
Unlike userspace memory allocation, kernel allocation APIs require an allocation policy (GFP flags) that depends on the current execution context.
Common APIs¶
kmalloc()¶
Allocates physically contiguous kernel memory.
kmalloc() automatically selects the smallest predefined kmalloc cache capable of satisfying the requested allocation size. The allocation request is then forwarded to the SLUB allocator.
Typical usage:
- Driver private data
- Runtime buffers
- Small to medium-sized allocations
kzalloc()¶
Allocates physically contiguous kernel memory and initializes all bytes to zero.
Internally, kzalloc() performs a kmalloc() allocation before clearing the allocated memory.
Typical usage:
- Driver objects
- Private structures
- State containers
kcalloc()¶
Allocates a zero-initialized array and performs integer overflow checking before calculating the total allocation size.
Internally, kcalloc() allocates memory through kmalloc(), performs integer-overflow checking, and zero-initializes the allocated memory.
Typical usage:
- Arrays of structures
- Descriptor tables
- Object arrays
kfree()¶
Releases memory previously allocated by the kernel allocator.
Passing NULL is safe.
vmalloc()¶
Allocates virtually contiguous memory.
Unlike kmalloc(), the returned virtual address may map to non-contiguous physical pages.
Typical usage:
- Large software buffers
- Large lookup tables
- Kernel data structures that do not require physically contiguous memory
GFP Allocation Flags¶
| Flag | Sleep | Typical Usage |
|---|---|---|
GFP_KERNEL |
Yes | Process Context, Workqueue, kthread |
GFP_ATOMIC |
No | IRQ Context, Atomic Context |
Allocation Path¶
The simplified allocation path implemented in the labs is:
kmalloc() serves as the public allocation interface, while the SLUB allocator manages fixed-size objects and the Buddy Allocator supplies page-backed slab memory.
API Selection¶
| Requirement | Recommended API |
|---|---|
| Driver object | kzalloc() |
| Generic allocation | kmalloc() |
| Array allocation | kcalloc() |
| Large allocation | vmalloc() |
| Release memory | kfree() |
kmalloc() vs vmalloc()¶
| Feature | kmalloc() |
vmalloc() |
|---|---|---|
| Virtual Address | Contiguous | Contiguous |
| Physical Address | Contiguous | Non-contiguous |
| Allocation Speed | Fast | Slower |
| Large Allocation | Limited | Better |
| DMA Friendly | Yes | Generally No |
GFP Selection¶
| Execution Context | Recommended GFP |
|---|---|
| Process Context | GFP_KERNEL |
| Workqueue | GFP_KERNEL |
| kthread | GFP_KERNEL |
| IRQ Context | GFP_ATOMIC |
| Holding Spinlock | GFP_ATOMIC |
Common Mistakes¶
- Using
GFP_KERNELinside an IRQ handler. - Allocating arrays with
kzalloc(n * size)instead ofkcalloc(). - Using
vmalloc()for small driver objects. - Forgetting to release allocated memory with
kfree(). - Performing unnecessary memory allocation inside interrupt handlers.