What Are devm_ APIs in Linux Device Drivers? – Free Linux Device Drivers Course in Hyderabad

Linux Device Driver Memory Allocation: devm_ APIs Explained
Free Linux Kernel Programming Course · Free Linux Device Drivers Course
15 min read
Beginner to Intermediate
Kernel 6.x Ready

devm_kzalloc
Linux device driver memory allocation
kcalloc
kmalloc_array
struct_size
Free Linux Kernel Development Course

If you are learning Linux device driver memory allocation, one of the very first things you must get comfortable with is choosing the right allocation API for the right situation. Kernel memory does not behave like user-space memory, and picking the wrong allocator can silently leak memory, crash your driver, or slow down your entire system.

This lesson is part of our free Linux kernel development course and free Linux device drivers course at EmbeddedPathashala. In simple, beginner-friendly language, we will look at how the kernel’s resource-managed devm_ family of allocation functions removes an entire class of bugs from your driver code, and we will also cover a handful of small but powerful slab helper APIs that every driver author should know.

What You Will Learn
  • Why manual kmalloc() / kfree() pairing is a common source of driver bugs
  • How the resource-managed devm_kzalloc() and devm_kmalloc() APIs solve that problem
  • When you should not use the managed allocation APIs
  • How to safely allocate memory for arrays using kcalloc() and kmalloc_array()
  • How struct_size() prevents dangerous integer-overflow bugs
  • How sensitive memory should be zeroed on free using the modern kfree_sensitive() API
Prerequisites
  • Basic familiarity with C pointers and structures
  • A working Linux machine with kernel headers installed for building modules
  • Some exposure to writing a “Hello World” kernel module is helpful but not required

Why Ordinary kmalloc() Is Risky Inside a Driver

Every driver that follows the Linux unified device model exposes at least two lifecycle callbacks: a probe() function that runs when the device is discovered, and a remove() function that runs when the device goes away. Any memory you allocate inside probe() with plain kmalloc() or kzalloc() must be freed inside remove(), and on every single error path in between.

In real driver code there can be five, ten, or more error paths inside probe() alone. Missing even one kfree() call on an error path introduces a memory leak that only shows up after the device has been plugged and unplugged hundreds of times in production. This is exactly the kind of bug that is easy to write and painful to debug — which is why the kernel gives driver authors a much safer alternative.

Manual Allocation vs Resource-Managed Allocation
probe() starts
→
kzalloc()
→
manual kfree() on every exit path
→
missed one? Memory leak
probe() starts
→
devm_kzalloc()
→
tracked by devres framework
→
auto-freed on detach, no leak

Resource-Managed Allocation: devm_kzalloc() and devm_kmalloc()

The kernel’s devres (device resource) framework provides managed versions of the memory allocator prefixed with devm_. Once memory is allocated through one of these functions, the kernel automatically releases it the moment the device is detached or the driver module is removed — whichever happens first. You do not need to call any matching free function at all.

Function Behaviour Typical Use
devm_kmalloc(dev, size, gfp) Allocates uninitialised memory, auto-freed on detach Buffers where you will fill every byte yourself
devm_kzalloc(dev, size, gfp) Allocates zero-initialised memory, auto-freed on detach Driver private-data structures (most common choice)
devm_kfree(dev, ptr) Frees managed memory early, before detach Rare — usually a sign the wrong API was chosen

Here is a simplified, original example showing a typical driver private-data allocation inside a probe() function:

struct mychip_data {
    void __iomem *regs;
    int irq;
    struct mutex lock;
};

static int mychip_probe(struct platform_device *pdev)
{
    struct mychip_data *data;

    data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    if (!data)
        return -ENOMEM;

    mutex_init(&data->lock);
    platform_set_drvdata(pdev, data);

    /* No explicit kfree() needed anywhere below this line */
    return 0;
}

Notice there is no matching kfree(data) anywhere in this snippet, and there does not need to be one. If probe() returns an error after this point, or if the driver is later unbound, the devres framework automatically releases data.

When NOT to Use devm_ APIs

This is one of the most common mistakes beginners make once they discover managed allocation: they try to replace every single kmalloc() call in the driver with devm_kmalloc(). Do not do this. The managed APIs are designed specifically for memory that should live for the entire lifetime of the device — typically allocated inside probe(). Memory with a shorter, more dynamic lifetime (for example, a buffer allocated per I/O request and freed as soon as that request completes) should still use ordinary kmalloc() / kfree(), because tying it to the device’s lifetime would keep it around far longer than necessary and waste memory.

A second point worth remembering: the managed allocation APIs are exported only to modules licensed under the GPL (or a GPL-compatible license). If you are building an out-of-tree module under a different license, these calls will not link.

Allocating Arrays Safely: kcalloc() and kmalloc_array()

Whenever you need memory for an array of elements, resist the temptation to write kmalloc(count * size, GFP_KERNEL) by hand. If count comes from user input, hardware, or the network, an attacker (or simply a corrupted value) can make count * size overflow, producing a tiny allocation while your code still writes as if it were huge — a classic and dangerous kernel security bug.

/* Risky - can silently overflow */
buf = kmalloc(count * sizeof(u32), GFP_KERNEL);

/* Safe - the kernel checks for overflow internally */
buf = kmalloc_array(count, sizeof(u32), GFP_KERNEL);

/* Safe AND zero-initialised */
buf = kcalloc(count, sizeof(u32), GFP_KERNEL);

kcalloc() is simply kmalloc_array() with the memory pre-zeroed, in the same way kzalloc() relates to kmalloc(). Managed equivalents also exist for driver-lifetime array allocations: devm_kcalloc() and devm_kmalloc_array().

struct_size(): Preventing Integer-Overflow Bugs

A very common kernel pattern is a structure that ends with a flexible array member — a fixed header followed by a variable-length payload. Calculating the total allocation size by hand (header size plus element count times element size) is another place where integer overflow bugs have historically crept in. The struct_size() helper macro performs this calculation safely.

struct sensor_reading {
    u32 timestamp;
    u8  channel_count;
    u16 samples[];   /* flexible array member */
};

struct sensor_reading *r;

r = kmalloc(struct_size(r, samples, channel_count), GFP_KERNEL);
if (!r)
    return -ENOMEM;

struct_size() automatically checks for overflow and, if the calculation would wrap around, returns a value that guarantees the allocation fails safely instead of succeeding with the wrong size. It is well worth browsing the kernel header include/linux/overflow.h to see the family of related helpers, including array_size() for plain array calculations.

Freeing Sensitive Memory: kfree_sensitive()

Older kernel documentation refers to a function called kzfree(), which behaved like kfree() but zeroed the memory before releasing it — useful for buffers that once held cryptographic keys or passwords. In modern kernels this function has been renamed to kfree_sensitive(), and kzfree() should be considered obsolete. If you see kzfree() in older tutorials or third-party code, treat it as a signal that the code predates current kernel conventions.

char *secret_key = kzalloc(KEY_LEN, GFP_KERNEL);

/* ... use secret_key ... */

kfree_sensitive(secret_key);   /* zeroes memory, then frees it */

Zeroing sensitive memory before it is returned to the allocator is a defence-in-depth measure: it reduces the chance that leftover key material can be read back out of freed memory by another part of the kernel later. Use it whenever a buffer has held secrets, and accept the very small performance cost as the price of that protection.

Real-World Use Case

Imagine you are writing a driver for a custom I2C sensor. In probe() you allocate the driver’s private-data structure with devm_kzalloc() so it is cleaned up automatically if the sensor is removed. Inside your read function, however, you allocate a short-lived buffer for a single I2C transaction using ordinary kmalloc(), because that buffer’s lifetime is a single function call, not the lifetime of the device. This combination — managed allocation for long-lived driver state, ordinary allocation for short-lived buffers — is exactly the pattern used throughout the mainline kernel driver tree.

Common Mistakes and Troubleshooting
Mistake Why It’s a Problem Fix
Blindly replacing all kmalloc() with devm_kmalloc() Ties short-lived memory to the device lifetime, wasting RAM Use managed APIs only for probe-time, device-lifetime allocations
Manual count * size multiplication Can silently overflow, causing an undersized buffer Use kmalloc_array() / kcalloc()
Calling devm_kfree() routinely Usually indicates the managed API was the wrong choice to begin with Re-evaluate whether the allocation should have been managed at all
Using kzfree() in new code Deprecated naming, may not exist in newer kernel trees Use kfree_sensitive() instead

Best Practices
  • Prefer devm_kzalloc() over devm_kmalloc() unless you have a specific reason to skip zero-initialisation.
  • Reserve managed allocation for data that genuinely lives as long as the device.
  • Always use the array-safe helpers (kcalloc(), kmalloc_array(), struct_size()) whenever a count comes from outside your own code.
  • Zero out any buffer that has held a key, password, or token using kfree_sensitive().

Performance Considerations

The devres bookkeeping used by devm_ functions adds a very small amount of overhead compared to plain kmalloc(), because the kernel has to track each allocation against the owning device. For the vast majority of drivers this overhead is negligible next to the safety it buys you. Where it does matter is in extremely hot code paths — for example, a buffer allocated and freed on every single interrupt. In that situation, a plain, non-managed allocation (or better still, a pre-allocated buffer reused across interrupts) is the right choice.

Security Considerations

Two security habits are worth internalising from this lesson. First, always use overflow-safe array allocation helpers rather than manual multiplication — this closes off a well-known class of kernel vulnerabilities. Second, treat any buffer holding secret data as sensitive and clear it with kfree_sensitive() rather than a plain kfree().

Summary and Key Takeaways
  • devm_kzalloc() / devm_kmalloc() automatically free memory when a device is detached, eliminating a whole class of leak bugs — but only for probe-time, device-lifetime data.
  • Use kcalloc() and kmalloc_array() instead of manual multiplication for array allocation.
  • struct_size() safely sizes allocations for structures that end in a flexible array member.
  • kfree_sensitive() is the modern replacement for the deprecated kzfree().

Conclusion

Choosing the right memory allocation API is one of those small decisions that has an outsized effect on driver reliability. By reaching for the resource-managed devm_ functions where they belong, and by using the overflow-safe array and struct-sizing helpers everywhere else, you remove entire categories of bugs before they can ever be written. In the next lesson of this free Linux device drivers course, we move on to how the kernel manages memory at the cgroup level, and revisit some important caveats around slab allocator sizing.

Frequently Asked Questions

Q1. What is the difference between kzalloc() and devm_kzalloc()?
kzalloc() requires you to call kfree() yourself. devm_kzalloc() ties the allocation to a device and frees it automatically on detach or module removal.

Q2. Can I use devm_ APIs outside of probe()?
You can, but it is discouraged. They are intended for allocations that should live as long as the device, which is almost always decided at probe time.

Q3. Why does kmalloc_array() exist instead of just multiplying manually?
Manual multiplication can silently overflow for large or attacker-controlled counts. kmalloc_array() detects that overflow and fails safely instead.

Q4. Is kzfree() still available in the latest kernels?
It has been renamed to kfree_sensitive(). New code should use the new name.

Q5. Do I need any special license to use devm_ functions?
Yes. These APIs are exported only to GPL-licensed (or GPL-compatible) kernel modules.

Q6. What happens if I call devm_kfree() manually?
It works, but needing to do so usually means a plain, non-managed allocation would have been the better choice from the start.

Q7. Does struct_size() work for any structure?
It is specifically designed for structures that end with a flexible array member, where the total size depends on a runtime element count.

Continue the Free Linux Kernel Development Course

This lesson is part of EmbeddedPathashala’s free Linux device drivers course and free embedded systems course.

Browse All Lessons

 

Leave a Reply

Your email address will not be published. Required fields are marked *