The GFP_ATOMIC vs GFP_KERNEL Flags: Why Kernel Allocators Need to Know Whether You Can Sleep

2026-08-20

Every call to kmalloc(), alloc_pages(), or the slab allocator takes a GFP ("get free pages") flag. This flag isn't a hint — it's a contract about what the allocator is allowed to do if memory is tight. Get it wrong and you either deadlock the kernel or leak pressure into the wrong subsystem.

The two flags that matter 95% of the time:

Other flavors layer on top: GFP_NOWAIT is GFP_ATOMIC without the reserve access; GFP_NOIO forbids starting new I/O (used inside block-layer code so reclaim doesn't recursively call back into the filesystem); GFP_NOFS forbids re-entering filesystem code (filesystems use this to avoid deadlocking on their own inode lock during writeback).

The classic bug: a network driver's interrupt handler allocates an sk_buff with GFP_KERNEL. Under memory pressure, the allocator tries to reclaim — which requires acquiring locks that some process, now preempted by this very interrupt, is holding. The system deadlocks. This is why in_atomic() checks and lockdep warnings exist: they catch this at development time.

Real-world example: the Linux TCP stack allocates receive buffers with GFP_ATOMIC during softirq packet processing. If GFP_ATOMIC allocations start failing (visible as SoftnetDropped in /proc/net/softnet_stat and allocstall events in /proc/vmstat), packets are silently dropped and TCP retransmits — you see it as latency spikes, not errors. The fix is usually raising vm.min_free_kbytes so the atomic reserve stays populated, not "make the buffer bigger."

Rule of thumb: if you can reach the call site by schedule()-ing to it (syscall, workqueue, kthread), use GFP_KERNEL. If you got there via an interrupt, softirq, tasklet, timer callback, RCU read-side, or while holding a spinlock/rwlock, use GFP_ATOMIC and always check the return value — NULL is a normal outcome, not a bug.

Modern kernels expose GFP_KERNEL_ACCOUNT for cgroup memory accounting and __GFP_RETRY_MAYFAIL for the middle ground: try hard, but give up before invoking the OOM killer.

Key Takeaway: GFP flags don't describe what you want — they describe what the allocator is permitted to do to get it, and sleeping while holding a spinlock is the fastest way to deadlock a kernel.

All newsletters