In Part 1 of this free Linux device drivers course lecture, we learned why the slab allocator exists and how kmalloc() routes a request to the right size class. Now it’s time to get hands-on: we will read live slab cache statistics straight from a running kernel, understand exactly what each column means, and extend our demo kernel module to exercise kzalloc(), krealloc(), and kfree() together, the same way a real device driver would.
Prerequisites
- Part 1 of this lecture (kmalloc and the slab allocator basics)
- A Linux VM with root access and kernel headers for your running kernel
- Comfort building and loading kernel modules with
make,insmod, andrmmod
Quick Recap: The Four kmalloc Cache Families
Before diving into tooling, it helps to recognize the four cache-name prefixes you will see on any modern kernel while working through this free Linux device drivers course:
| Prefix | Meaning |
|---|---|
kmalloc-N |
Plain general-purpose cache for N bytes |
kmalloc-rcl-N |
Reclaimable variant, freed back more aggressively under memory pressure |
kmalloc-cg-N |
Charged against a cgroup’s memory limit (containers) |
dma-kmalloc-N |
Guaranteed reachable by legacy DMA-limited devices |
Three Ways to Inspect Slab Caches Live
1. /proc/slabinfo — The Raw Source of Truth
Every slab-inspection tool ultimately reads this file. You need root to see it in most distro configurations:
$ sudo cat /proc/slabinfo | head -n 5
$ sudo cat /proc/slabinfo | grep "^kmalloc"
2. vmstat -m — A Convenient Wrapper
vmstat‘s slab mode reformats the same data with clean column headers:
$ sudo vmstat -m | grep "^kmalloc"
3. slabtop — Real-Time, Sorted View
For a continuously refreshing, top-like view sorted by cache size, run:
$ sudo slabtop -o
The -o flag prints one snapshot and exits, which is friendlier for scripting or quick checks than the default live-refresh mode.
Understanding the Output Columns
| Column | Meaning |
|---|---|
| active_objs / Num | Objects currently in use by some part of the kernel |
| num_objs / Total | Total objects the cache currently holds, used or free |
| objsize / Size | Size in bytes of a single object in this cache |
| pagesperslab / Pages | How many pages back each slab in this cache |
A quick tip while learning: run sudo slabtop -o right after loading a new driver, then again after unloading it. If active object counts for a cache don’t return to their prior levels, that’s a strong early signal of a memory leak in the driver.
Writing a Fuller kmalloc/krealloc/kfree Kernel Module
Let’s extend the demo from Part 1 to also exercise krealloc(), which resizes an existing allocation — a pattern you’ll use whenever a driver’s buffer needs to grow at runtime.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
static char *epath_buf;
static int __init epath_slab_lab_init(void)
{
size_t initial_size = 64;
size_t grown_size = 256;
epath_buf = kzalloc(initial_size, GFP_KERNEL);
if (!epath_buf) {
pr_err("epath_slab_lab: initial allocation failed\n");
return -ENOMEM;
}
pr_info("epath_slab_lab: allocated %zu bytes\n", initial_size);
epath_buf = krealloc(epath_buf, grown_size, GFP_KERNEL);
if (!epath_buf) {
pr_err("epath_slab_lab: krealloc failed\n");
return -ENOMEM;
}
pr_info("epath_slab_lab: grown to %zu bytes\n", grown_size);
snprintf(epath_buf, grown_size, "EmbeddedPathashala krealloc lab\n");
pr_info("epath_slab_lab: content = %s", epath_buf);
return 0;
}
static void __exit epath_slab_lab_exit(void)
{
kfree(epath_buf);
pr_info("epath_slab_lab: buffer released\n");
}
module_init(epath_slab_lab_init);
module_exit(epath_slab_lab_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EmbeddedPathashala kmalloc/krealloc/kfree lab module");
Load it and watch both dmesg and slabtop at the same time in two terminals to see the cache usage shift in real time:
$ make
$ sudo insmod epath_slab_lab.ko
$ dmesg | tail -n 6
$ sudo slabtop -o | grep kmalloc
$ sudo rmmod epath_slab_lab
Real-World Use Cases
- USB drivers often
krealloc()descriptor buffers as they parse variable-length device descriptors. - Character drivers commonly grow a read/write buffer with
krealloc()when userspace requests a larger transfer than initially provisioned. - System administrators use
slabtopin production to hunt down runaway kernel memory usage caused by a buggy driver or module.
Common Mistakes and Troubleshooting
| Mistake | Fix |
|---|---|
Using the old pointer after krealloc() fails |
Always assign to a temporary pointer first, check for NULL, then commit |
Assuming /proc/slabinfo is readable without root |
Most distributions restrict it to root; always test with sudo |
Best Practices
- Check
slabtopbefore and after stress-testing a new driver to catch leaks early. - Never rely on the exact byte size of a kmalloc cache in your driver logic — cache boundaries can shift between kernel versions.
- Use
ksize()if you need to know how much usable space you actually got back from a kmalloc call.
Performance Considerations
Repeated krealloc() calls that grow a buffer one small step at a time are expensive, because each growth can trigger a fresh allocation and a full copy of the old data. If you know a buffer will grow, size it generously up front rather than growing it byte by byte.
Security Considerations
When you enlarge a buffer with krealloc(), remember that the newly added bytes are not zeroed automatically. If that extra space could ever be copied to user space, zero it explicitly, or use kzalloc() plus manual copying instead, to avoid leaking uninitialized kernel memory.
Summary / Key Takeaways
/proc/slabinfois the raw source;vmstat -mandslabtopare convenient front-ends over the same data.- Compare cache statistics before and after loading a driver to catch leaks quickly.
krealloc()lets a driver grow a buffer at runtime, but newly added bytes are not zeroed automatically.
Conclusion
You now have a practical, tool-based workflow for observing exactly how your kernel module interacts with the slab allocator, plus a working module that exercises kzalloc(), krealloc(), and kfree() together. This combination of theory and live inspection is exactly the kind of hands-on skill this free Linux device drivers course and free Linux kernel development course are built around. Keep experimenting with slabtop on your own modules — it is one of the fastest ways to build real intuition for kernel memory behavior.
Frequently Asked Questions
On most distributions, yes. Use sudo cat /proc/slabinfo to view it.
slabtop gives a continuously refreshing, sorted live view, while vmstat -m prints a single formatted snapshot — both read the same underlying /proc/slabinfo data.
No. Only the original bytes are preserved; any newly added space is left uninitialized, so zero it yourself if it will ever reach user space.
Snapshot slabtop output before loading your module and again after unloading it. If active object counts for the relevant cache don’t drop back down, you likely have a leak.
Yes, on kernels built with SLUB (which is every current kernel), each cache exposes a directory of tunables and statistics under /sys/kernel/slab/<cache-name>/.
It’s best to use a disposable virtual machine. Kernel module bugs can crash or destabilize the whole system, so keep experiments isolated from your daily-use machine.
More free lectures on kernel internals, device drivers, and embedded Linux are available at EmbeddedPathashala.
