LWN.net Logo

The latest loadable module changes

Most of the problems with the new module loader have long since been ironed out. A few issues, remain, however. For example, module versions have not yet been implemented; kernel developers tend to dislike (and not use) that feature, so it has been relatively low on the list of priorities. There still is no modversions patch up for review, but a related issue has been resolved.

The modversions facility allows a binary kernel module to be loaded into multiple kernel versions, as long as the relevant data structures and function prototypes have not changed. It works by attaching a simple checksum to function and variable names, and refusing to load a module if the checksums no longer match. See Linux Device Drivers, Chapter 11 for details.

But modversions has never been able to catch all of the things that could make a module incompatible with a given kernel. The most common problem (a module compiled for SMP loaded into a uniprocessor kernel, or vice versa) was handled by hacking "smp" into the checksum. But other potential incompatibilities - compiler versions, memory model (for systems with high memory), whether preemption is configured in, etc. - are not detected until something goes badly wrong.

A patch from Rusty Russell fixes that problem, whether or not modversions is in use. Compilation and configuration options which can break module compatibility are stored in a special section in the kernel and in each loadable module; the information is stored as a simple string like "SMP,preempt,gcc-2.95." If the strings don't match when a module is loaded, the kernel puts out a warning.

One other loadable module issue still hasn't gone away: how to deal with modules which fail at initialization time. The new module loader, when first merged, took great pains to hide a module from the rest of the kernel until it had completed initialization. That way, the kernel could be sure that no other kernel code was already trying to use the module if its initialization fails and it is removed from the kernel. Unfortunately, that feature broke the disk subsystem, which wants to read partition tables from disks when the disks are registered. That read would fail, because the module which actually implemented disk reads was not yet available, and the partitions would fail to show up in the system. To get around this problem, the module code was changed to make modules visible during the initialization process.

That change fixed the disk problems, but it also brought back the old race condition: a module can be removed while the kernel is trying to use it. It is clearly an uncommon situation, but Rusty worries about things like this. So he has posted a new patch to address the problem. With this patch, modules are again invisible until they are properly initialized. Should there be a need to provide access to a particular module while initialization is still in progress, a call to the new module_make_live() function will make that possible. The add_disk() function calls module_make_live() itself, so there is no need to change any drivers to keep disks working. There is also a new notifier chain for any part of the kernel that wants to know when modules come online.

Some developers will likely see the new approach as another unnecessary fix for a problem which never happens in the real world. It is, however, a small change which closes off a set of possible failures, and is thus worth consideration.


(Log in to post comments)

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