LWN.net Logo

Module reference counts - back to the future?

In the 2.2 (and prior) kernels, loadable modules were charged with the task of maintaining a count of references to the module. When the reference counting was done correctly, the kernel knew when it was safe to unload a module. Unfortunately, the maintenance of the reference counts often was not done right, and, in any case, in-module reference counting was subject to certain small but unavoidable race conditions. Simply put, there was no way to completely avoid situations where the kernel was executing module code while the module's reference count was zero.

Starting in 2.3, the reference counting task moved slowly outside of the modules themselves. For example, the file_operations structure exported by char drivers got an owner field which points to the module. Before the kernel will, say, call a module's open() method, it increments the reference count. This mechanism puts the reference count in one place (rather than in hundreds of module open() methods) and eliminates race conditions. In 2.5, this mechanism was extended further, and attempts to increment reference counts were allowed to fail (for example, when the module still exists, but is being unloaded).

This mechanism works reasonably well for most device drivers; the interface between the kernel and the module is narrow, and references to the module are limited to a few types of objects (open files and memory mappings). Life gets harder, however, when you get into other parts of the kernel. A recent discussion on the netdev list, started by the discovery of a situation where the networking subsystem can call into a module which has been unloaded, shows how hard it can be.

The networking code keeps track of a vast array of objects, each of which can reference others, and each of which must be reference counted. A networking module can only be unloaded when all of those objects are no longer referenced and have been cleaned up. The immediate problem has to do with network devices (exported by network device drivers); numerous parts of the kernel can reference such a device. So the device itself contains a reference count. In some situations, however, the kernel can remove a driver module even though a particular device's reference count had not dropped to zero. One solution to the problem, as proposed by Rusty Russell, is to increment the module's reference count every time one of its network device's count goes up. The problem with this approach, according to David Miller, is that devices are just the beginning.

So you propose to add this kind of thing for every ARP entry, every route cache entry, every IPSEC policy, every socket, every struct sock, every networking dynamic object ever created? When we add SKB recycling, will we need to do a module get/put on every SKB alloc/free/clone/copy? I think this way lies insanity :)

The insanity comes from the fact that attempts to increment module use counts can fail. Trying to add an unbelievable number of failure paths to the networking code to deal with this case does indeed seem like a one-way ticket to the funny farm. All this extra reference counting also adds significant overhead to the networking code's hand-crafted fast paths; that is a penalty that the networking hackers are not prepared to accept.

The solution that some of the networking developers are asking for is to go back to having modules maintain their own reference counts - sort of. At the least, modules need some way of saying whether they can or cannot be unloaded at a particular time. Usually that decision is just a matter of looking at the internal objects they have to maintain anyway. So the addition of a simple can_unload() function to many modules would solve the immediate problem.

There is still another problem, though: actually getting a complex module to a state where it can be unloaded can be a tricky task. Removing a network protocol, for example, requires shutting down the protocol and waiting for all objects to be freed. Little details (like sockets which must, according to the protocol specification, sit in a 60-second TIME_WAIT state before going away) complicate the picture and can make the unload process take a long time. Users tend to worry when an rmmod command appears to just hang. Handling all the details of that case (especially if you want to allow users to interrupt the rmmod operation) gets to be tricky indeed. Possible solutions are being discussed, but no implementations are currently on the horizon.

Of course, one could always go back to Rusty's suggestion from the 2002 Kernel Summit: simply do not allow modules to be removed from the kernel.


(Log in to post comments)

can_unload() is racy by definition

Posted May 8, 2003 3:09 UTC (Thu) by proski (subscriber, #104) [Link]

can_unload() can return "true" now and "false" one millisecond later for the reasons known only to the module. No amount of locking outside the module code can prevent it. Checking if the safe unload is possible and the unload itself should be done atomically. In other words, module unloading should be allowed to fail in the module itself.

Still, I think that most modules should keep reference count rather than count things when it's time for the module to be unloaded.

can_unload() is racy by definition

Posted May 8, 2003 21:37 UTC (Thu) by iabervon (subscriber, #722) [Link]

I think it would work to have a get/put_permission_to_unload() pair, such that can_unload() is only called with permission_to_unload held, and if can_unload() returns true, it cannot return false unless the permission_to_unload is dropped (which is to say, can_unload() once returns true once the creation of new references into the module is blocked and no such references still exist). Once can_unload() returns true, the module has given up its right to refuse unloading, at least unless the unloading code decides to preserve it.

Logically, if it is safe to unload now, it must be safe to unload later (otherwise it isn't really safe now; it's merely not certain to cause problems). Therefore, after returning true to can_unload(), it shouldn't be legal to return false. It's also presumably helpful to signal that something wants the module to prepare to be unloaded and to signal that the attempt to unload has been cancelled. But any can_unload() without internal races must be able to demonstrate that the module can't stop being unloadable while the call is in progress; it should be able to extend this guarantee to the future.

can_unload() is racy by definition

Posted May 15, 2003 14:48 UTC (Thu) by eduperez (guest, #11232) [Link]

> Logically, if it is safe to unload now, it must be safe to unload later

No, it isn't. Imagine the driver of a removable block device (i.e., a SCSI ZIP drive), which gets loaded when the block device is mounted. It is safe to unload the module as soon as the block device is unmounted. But it can be mounted again by the user and the module becomes not-unloadable.

can_unload() is racy by definition

Posted May 15, 2003 17:30 UTC (Thu) by iabervon (subscriber, #722) [Link]

If the user might mount the device again, it's not safe to unload the module. The module has to arrange for the user to be prevented from using the device (with this instance of the module), and then it is safe, and will remain safe until something changes.

"Is it safe to do X? Yes, but there's a potentially dangerous race condition." doesn't make sense, because a potentially dangerous race condition means it is not safe.

Why, in 2.5, do modules need to be unloaded?

Posted May 8, 2003 8:00 UTC (Thu) by ctg (subscriber, #3459) [Link]

- Modules aren't loaded for device discovery any more?
- Memory, in the general case, is enough so that there is little merit in unloading the drivers for hotplugged devices once they are unplugged to conserve resource?
- Non hotpluggable devices don't need their modules unloading...?

The only reasons I can think of are
- Because you are developing a driver and are going through the "edit->compile->link->load->test" cycle
- Because your hardware has become "wedged" and you want to re-intialise it or whatever

Both these case are rare/extreme - so can module unloading either be protected by some great big monolithic lock. Or the onus is on the human unloading to make sure that whatever is using the module really has finished - and nothing will come along again to use it....?

Can the second case (re-intialise) be accomplished by not having to unload/reload the module (modprobe --reinitialise <module> for example).

Why, in 2.5, do modules need to be unloaded?

Posted May 8, 2003 11:29 UTC (Thu) by vivek (guest, #6962) [Link]

You could have incompatible modules. For example, the nistnet module
won't co-exist with the RTC module, but you don't want the nistnet
module loaded all the time: normally you tweak modules.conf to make
them swap each other out on load.

Unloadable modules also allow you to patch and replace modules without a
reboot, which can be very handy. And hardware (especially on machines
that can suspend) can require modules to be unloaded and reloaded around
a suspend/resume operation (the sound on my laptop, for instance).

Losing the ability to unload/reload modules would basically be giant leap
backwards: A whole set of hardware problems would become solvable only
with a reboot, instead of a module reload.

And as for the memory assumption - sure, in a random desktop/server box
there might be plenty of memory, but what if you have a small appliance
type thing with hot-pluggable hardware extensions and limited memory?

Losing module unload just doesn't seem like a good idea to me.

Why, in 2.5, do modules need to be unloaded?

Posted May 8, 2003 18:38 UTC (Thu) by hazelsct (guest, #3659) [Link]

The only reasons I can think of are
  • Because you are developing a driver and are going through the "edit->compile->link->load->test" cycle
  • Because your hardware has become "wedged" and you want to re-intialise it or whatever
I run into both of these quite frequently. When developing the visor driver for my new PalmOS device not on the list in visor.h, I needed to repeatedly unload-reload. I suppose this can now be done using UML, but having to shut down and restart an image is a whole lot harder than unloading and reloading a module.

Likewise, the eepro100 driver fails when my laptop suspend/resumes, so I need to unload it on suspend and reload it on resume. And the network driver on my VIA EPIA system falls down whenever there's not enough power, requiring a reload.

I don't think I'm atypical; I'm not much of a kernel hacker, though somewhat above the casual user. It's unwise to drop a whole segment of user-developers in this range, don't you think?

Regarding memory, speak for yourself; not everybody uses a Commodore Amiga 2000 like myself, but ignoring the low-memory case risks eliminating an entire class of Linux use in embedded devices.

Why, in 2.5, do modules need to be unloaded?

Posted May 8, 2003 22:32 UTC (Thu) by dlang (✭ supporter ✭, #313) [Link]

geven that during the debugging cycle you are by definition working with defective code, how can you really be sure that your system is intact after you have loaded the module the first time? All the arguments about how the mere loading of a nVidia driver even if you only use VGA 80x25 text mode taints the kernel and could be the cause of ANY crash that happens becouse the module could have scribbled over any part of kernel memory would also seem to apply to the module you are debugging.

Why, in 2.5, do modules need to be unloaded?

Posted May 9, 2003 23:40 UTC (Fri) by proski (subscriber, #104) [Link]

during the debugging cycle you are by definition working with defective code, how can you really be sure that your system is intact after you have loaded the module the first time?
There is a logical fallacy here. All defects in the driver are assumed to affect the rest of kernel. In fact, some defects may be just in the way how the device is programmed. If the device is reset on the module load, there is no way for the old code to affect the newly loaded module.

Why, in 2.5, do modules need to be unloaded?

Posted May 8, 2003 20:34 UTC (Thu) by dlapine (guest, #7358) [Link]

Ever use the gm module for myrinet? You must unload the module and reload it in a different mode if you want to statically map a cluster of myrinet capable machines. Rebooting them to accomplish this task is not trivial.

We have (or will shortly) over 1400 machines at our site alone that need to do this at least quarterly. This is not a "corner case".

Simply locking all modules in the kernel removes too much usefulness.

Why, in 2.5, do modules need to be unloaded?

Posted May 9, 2003 23:18 UTC (Fri) by Peter (guest, #1127) [Link]

Ever use the gm module for myrinet? You must unload the module and reload it in a different mode if you want to statically map a cluster of myrinet capable machines. Rebooting them to accomplish this task is not trivial.

Not that I disagree with the need to be able to unload modules. I love having that ability. But in this particular case, I think that it's merely a design choice by the myrinet module writer. Since it is easy to reload a module, why bother to provide a runtime configuration interface? If this were no longer the case, I think someone would write such an interface, so instead of reloading the module to reconfigure static routes, you would poke something into /sys/.

Why, in 2.5, do modules need to be unloaded?

Posted May 9, 2003 18:01 UTC (Fri) by Max.Hyre (subscriber, #1054) [Link]

Because you're running radically different devices through one port?

I haven't looked at any recent (i.e., > 2.0.x :-) kernels, but when I want to sync my laptop with my desktop, I unload the printer module, and load the PLIP module.

Why, in 2.5, do modules need to be unloaded?

Posted May 10, 2003 8:37 UTC (Sat) by wolfrider (guest, #3105) [Link]

--Yep, and don't forget cases like VMWare, which can't allow the guest system access to things like the printer unless you rmmod the Linux driver first...

--Seriously, my guess is that Rusty is prolly a pretty nice guy IRL, but this "idea" of his is so ludicrous it's hard to fathom... Musta been a brain fart.

--I LIKE not having to reboot my linux boxes every day...

Why, in 2.5, do modules need to be unloaded?

Posted May 17, 2003 5:14 UTC (Sat) by hpreg (guest, #9842) [Link]

"when I want to sync my laptop with my desktop, I unload the printer module, and load the PLIP module."

"VMware, which can't allow the guest system access to things like the printer unless you rmmod the Linux driver first"

Those 2 things actually are the consequences of 1 single bug: the line printer module (lp) claims the physical parallel port on module load, and releases it on module unload, instead of claiming it on device open (/dev/lp<x>) and releasing it on device close.

If somebody fixes this bug (which should not be too hard), then there is no absolute need to be able to unload "lp" anymore, as all other parallel port drivers (PLIP, VMware) will then be able be loaded concurrently with lp.

In summary, I'm just saying that lp is not a good argument to use against Rusty's "it is OK not to be able to unload modules" theory.

Copyright © 2003, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds