In this lesson, you will learn how to monitor the SLUB allocator to identify memory fragmentation and subtle object leaks that aren't immediately visible via standard page-level metrics.
Understanding SLAB/SLUB Health
The kernel manages small memory objects using the SLUB allocator, which organizes memory into "slabs"—chunks of pages divided into fixed-size slots for specific kernel structures (like task_struct or inode). When the kernel requests memory, it grabs an object from an existing slab. If a slab becomes underutilized or fragmented, we waste precious physical memory.
Memory leaks occur when objects are allocated but never returned to their respective slabs. Because these objects are often small, they don't trigger "out of memory" (OOM) conditions immediately, but they slowly inflate the SUnreclaim or SReclaimable fields in /proc/meminfo, leading to performance degradation as the kernel struggles to find contiguous cache lines.
Tracing Allocations with eBPF
To diagnose this, we focus on the allocation and free functions: kmem_cache_alloc and kmem_cache_free. By attaching kprobes to these functions, we can aggregate the number of active objects per cache name.
Consider this logic for a BPF trace program:
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, char[32]); // Cache name
__type(value, long); // Net balance
} slab_tracker SEC(".maps");
SEC("kprobe/kmem_cache_alloc")
int B_alloc(struct pt_regs *ctx) {
// Increment the count for the specific cache being allocated
return 0;
}
SEC("kprobe/kmem_cache_free")
int B_free(struct pt_regs *ctx) {
// Decrement the count
return 0;
}
By observing the "net balance" (Allocations minus Frees) for each cache name over time, you can pinpoint which specific kernel subsystem is failing to release objects. If a specific slab like dentry or filp continues to grow without bound, you have identified a leak. Similarly, observing the frequency of kmem_cache_alloc failures or high fragmentation in slabinfo allows you to correlate workload patterns with memory exhaustion, helping you distinguish between a genuine leak and simply inefficient object caching.
Key Takeaway: By tracking the net balance of allocations against frees per slab cache using eBPF, you can isolate exactly which kernel structure is leaking memory or causing fragmentation, bypassing the limitations of coarse-grained system monitoring.