Several people (myself included) have reported intermittent problems
with 2.4.0-test kernels, where compilation goes fine but modules
built with CONFIG_MODVERSIONS=y won't load due to symbol mismatches.
Symbols from i386_ksyms will be exported by the kernel with unexpanded
version fields, i.e. `foo_R__ver_foo' instead of `foo_Rxxx'.
I've now identified the cause of these problems: make's time-of-
modification based dependency analysis is UNRELIABLE on fast machines
where the file modification time resolution is in whole seconds.
In the case of the Linux kernel, this is what should happen:
1. We do a `make dep' at the top level.
2. `make dep' recurses and does a `fastdep' in each subdir.
3. fastdep updates .ver files from .c files that export symbols,
and collects all .ver files in include/linux/modules/.
4. In each subdir, we tell make that modversions.h depends on
this subdir's .ver files. If any .ver file was updated or newly
made, make executes the rule which rewrites modversions.h to
#include all current .ver files. Thus, modversions.h is always
up to date.
This is what happens when the bug hits you:
5. `make fastdep' visits lib/ and updates modversions.h;
modversions.h gets modification time T0 = CURRENT_TIME.
6. `make fastdep' next visits arch/i386/kernel/;
i386_ksyms.ver is made (and perhaps a few other),
and gets modification time T1 = CURRENT_TIME; however,
on a fast machine, T1 == T0 with non-zero probability.
7. `make' now compares T0 with T1; since !(T1 > T0), `make'
concludes that modversions.h doesn't need to be updated.
(See remake.c:check_dep() in the GNU make sources.)
8. arch/i386/kernel/ is the last subdir with exported symbols
visited by `make fastdep', so we have no further opportunities
to remake modversions.h in other subdirs; thus, modversions.h
remains incomplete without #including i386_ksyms.ver.
9. The kernel's symbol table will now have have unexpanded version
fields for the i386_ksyms symbols, leading to symbol mismatches
at attempts to load modules.
At http://www.csd.uu.se/~mikpe/linux/modverbug/ you'll find a sample
Makefile which illustrates the essence of Linux' `make fastdep'.
On my machine, it fails to remake modversions.h about once every
3-5 tries.
Possible solutions:
A. Increase the resolution of file modification times to microseconds.
Probably not practical right now (2.4 release, glibc binary compat.),
but IMHO necessary in the near future.
B. Change GNU make to use >= instead of > when comparing modification
times. Not an option -- incompatible semantic change.
C. Change the Linux kernel to work around this problem. We either:
C1. forcibly remake modversions.h in each subdir's `fastdep', or
C2. don't create modversions.h at all in the subdirs, but only
once in the toplevel Makefile after doing dep-files.
I'll do a patch to implement solution C1, unless someone has
a much better idea.
/Mikael
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Mon Jul 31 2000 - 21:00:23 EST