Site icon New Generation Enterprise Linux

Stop getting burned by kernel modules that refuse to unload

Kernel News & Module Management

Stop getting burned by kernel modules that refuse to unload

Technical Briefing | 7/14/2026

We have all been there. You update a driver or swap out a network interface module, you run modprobe -r, and the kernel tells you the module is in use. No other info, no hints. You check lsof, you grep through your active processes, and everything looks clean. But the reference count stays stubbornly at one. This bit me hard last month on a bunch of production storage nodes where a stale module reference was silently killing our ability to apply security patches without a reboot.

Why the reference count is lying to you

Usually, if a module won’t unload, something is still holding a handle on it. But in the modern kernel, that something isn’t always a userspace process. It could be an orphaned block device, a lingering sysfs entry, or even a hardware interrupt that never finished its clean-up routine. If you are just relying on lsmod output, you are missing the internal dependencies that the kernel tracks deep in its own memory structures.

cat /sys/module/YOUR_MODULE_NAME/refcnt
lsmod | grep YOUR_MODULE_NAME
grep -E '^(module_name|refcount)' /proc/modules
  • Check /proc/modules for the third column to see which process IDs might be holding onto a module lock
  • Look into /sys/kernel/debug/tracing/events/module to see if specific load or unload events are being blocked by a hung thread
  • Use sysfs to inspect the holders directory if your kernel is recent enough to expose object relationships

If you really need to force the issue, modprobe -f is a trap. I have seen it result in a kernel panic more times than I can count because it ignores the safety checks that exist for a reason. If a module says it is in use, the kernel is trying to prevent a NULL pointer dereference or a race condition. Instead of forcing it, try to trace exactly what file descriptor is still open under /proc/self/fd or check if a systemd service is still lurking in the background with a dead connection to that hardware.

The next time you hit this, don’t just reach for a reboot. Take a look at your dmesg buffer immediately after the failed unload attempt. The kernel often logs the specific function call that is keeping the reference alive, even if it doesn’t shout it at you in the modprobe output. Digging into the ring buffer is usually the difference between a quick fix and an unnecessary maintenance window.

Linux Admin Automation  |  © www.ngelinux.com  |  7/14/2026
0 0 votes
Article Rating
Exit mobile version