skip to content

On Linux, rmmod refuses to remove a kernel module and reports that it is in use. What is the kernel actually counting, and how do you find out what is holding the module?

level: middleimportance: should knowfreq 50%

answer

  1. a counter, not a lock
  2. zero or nothing happens
  3. modules named, users only counted
  4. holders directory in sysfs
  5. some modules have no exit path

basics

~20 s

Each module has a reference count, and the kernel only unlinks it when that count is zero. References are taken by anything using the module: an open device node, a mounted filesystem, a configured interface, or another module that depends on it.

solid answer

~50 s

The kernel keeps a per-module reference count and will not unload a module while it is non-zero, because unlinking code that something still has a pointer into would crash the machine. Two kinds of holders exist. Other *modules* that depend on it are named — `lsmod` prints them in the "Used by" column, and they are also listed as symlinks under `/sys/module/<name>/holders/`. *User-space and kernel* users are counted but not named: `/sys/module/<name>/refcnt` gives you the number, and you have to reason from what the module provides — unmount the filesystem it implements, bring down the interface its driver owns, stop the process holding its device open. `modprobe -r` is usually the better command than `rmmod` because it also drops the dependencies that become unused. Forcing an unload requires a kernel built with force-unload support and is a genuine crash risk, and a module written without an exit routine can never be unloaded at all.

go deeper

for a junior

Know that a module can only be removed when nothing is using it, and that the third column of lsmod is a use count. Say that you would stop whatever uses the module rather than forcing the removal.

for a middle

Explain the reference count as a kernel-side counter, distinguish named module holders (lsmod's Used by column, the sysfs holders directory) from unnamed users, and know that modprobe -r walks the dependency chain.

for a senior

Show the diagnostic path on a live host: read the count, rule out module holders, reason from what the module provides to the unmount or interface change that releases it, and explain why forcing an unload risks an oops and why reloading a driver is service-affecting.

for a principal

Frame it as a change-management question: a driver that cannot be unloaded means the fix window is a reboot, so a fleet needs a story for rolling reboots, kernel live-patching scope, and vendors whose modules leak references.

## Why a reference count exists Unloading a module frees the memory its code and data occupy. If anything in the kernel still holds a pointer into that memory — an open file whose operations table lives in the module, a registered filesystem, a timer that will fire later, a network device — the next dereference lands in freed memory. There is no fault handler that saves you; it is a kernel oops. So the module framework counts users. Subsystems take a reference when they hand out something backed by the module and drop it when that thing goes away. `rmmod` asks the kernel to remove the module; the kernel checks the count and returns `EBUSY` if it is non-zero, which the tool prints as the module being in use. ## Reading the count and the named holders ```bash lsmod | head -3 # Module Size Used by # xfs 2binary 1 <holder-module> cat /sys/module/xfs/refcnt # the number ls /sys/module/xfs/holders/ # the module-level holders, by name ``` The third `lsmod` column is the reference count; the names after it are the modules that depend on this one. Those same names appear as symlinks in `/sys/module/<name>/holders/`. The underlying data comes from `/proc/modules`, which `lsmod` simply formats. The important asymmetry: **module holders are named, everything else is only counted.** A count of 3 with an empty holders directory means three users the kernel does not identify for you. ## Finding an unnamed holder Reason from what the module provides, then remove the user: - **A filesystem module** is held for as long as a filesystem of that type is mounted. Unmount it. If the unmount itself fails because the mount is busy, that is a separate problem — some process has a file open or a working directory inside it. - **A network driver** is held while its interface exists or is up. Bring the interface down; for some drivers the reference persists while the device is registered at all. - **A character or block device driver** is held while a process has the device node open, or while a device it created is in use. - **A crypto, compression or helper module** is typically held by another module, so it will show up as a named holder. This is also why `modprobe -r <name>` is usually what you want: it removes the module and then walks back down the dependency chain removing anything left unused, so you do not have to unload four helper modules by hand in the right order. ## The cases where it will never unload - **No exit routine.** A module can be written without an unload path. The kernel marks it permanent; there is no sequence of commands that will remove it short of a reboot. - **A leaked reference.** A buggy module can take a reference and fail to drop it. The count then never returns to zero even though nothing is genuinely using it, and the module is stuck for the life of the boot. This is a real class of driver bug and a legitimate answer in an interview. - **Force unload.** `rmmod -f` exists but only works on a kernel built with forced unloading enabled, which distribution kernels generally are not. Even where it works it does exactly what the reference count was protecting you from: it removes the code while something may still be pointing at it. It is a development tool, not an operations tool. ## Why interviewers ask this The question separates "in use means something is using it" from an actual model. A candidate with the model immediately splits holders into named modules and unnamed users, knows where each is visible, knows that `modprobe -r` handles the dependency chain, and knows that forcing is a crash and not a fix. A candidate without it reaches for `-f` or reboots. One related habit worth mentioning: unloading and reloading a driver on a production host is not a neutral operation. Reloading a network driver drops link and resets the device's configuration; reloading a storage driver can take the disks away underneath a mounted filesystem. The reference count is protecting the kernel's memory, not your service — it will happily let you unload a module whose removal is a bad idea, so long as nothing holds a reference.

  • The reference count is 1 but the holders directory is empty. What does that tell you?
    That the holder is not another module — it is a user-space or in-kernel user the module framework does not name: an open device node, a mounted filesystem of that type, a live network interface. You have to work it out from what the module provides, then release it. An empty holders directory rules out the dependency chain, which is useful negative information.
  • Is rmmod -f a reasonable way out when a module will not unload?
    No, outside driver development. Forced unload only works on kernels built with that option, and it removes the module's code while the reference count says something may still be pointing into it — the exact condition the count exists to prevent. The usual outcome is an oops or a subtly corrupted kernel. Fix the holder, or reboot.
  • Why prefer modprobe -r over rmmod in normal operation?
    Because dependency chains are common. `rmmod` removes exactly the module you name, leaving its helper modules loaded with a now-zero count. `modprobe -r` removes the target and then any dependencies that have become unused, in the correct order. It also honours the site configuration in /etc/modprobe.d, which `rmmod` does not read at all.

saying these in an interview costs you the question

  • Thinks "in use" means a user is logged in
  • Reaches for rmmod -f as the normal fix
  • Believes lsmod names every holder of a module
  • Assumes every module can be unloaded eventually
  • Says reloading a driver is a harmless operation

context