The latest loadable module changes
[Posted January 15, 2003 by corbet]
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)