* [PATCH] automatic initcalls
@ 2002-07-27 20:22 Roman Zippel
2002-07-28 3:31 ` Rusty Russell
0 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-07-27 20:22 UTC (permalink / raw)
To: linux-kernel; +Cc: Rusty Russell, Kai Germaschewski
[-- Attachment #1: Type: text/plain, Size: 617 bytes --]
Hi,
This patch is based on Rusty's patch, I did these changes to get it
working:
- I only look at modules which contain an initcall
- I only order initcalls of level 6 and 7
This makes the problem managable, so that everything what can be built
as module is also correctly initialized when compiled in. Other
initcalls still have to be ordered manually, but these are the minority
and so easier to manage.
I had to push up a few initcall levels and fix a bug in the IDE driver,
but otherwise it seems to work fine.
I also included my version of KBUILD_MODNAME (IMO my version should be a
bit faster :) ).
bye, Roman
[-- Attachment #2: initcall.diff --]
[-- Type: text/plain, Size: 10214 bytes --]
Index: Makefile
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/Makefile,v
retrieving revision 1.1.1.30
diff -u -p -r1.1.1.30 Makefile
--- Makefile 27 Jul 2002 12:34:13 -0000 1.1.1.30
+++ Makefile 27 Jul 2002 13:19:29 -0000
@@ -268,6 +268,7 @@ cmd_link_vmlinux = $(LD) $(LDFLAGS) $(LD
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -284,9 +285,25 @@ define rule_link_vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+init/generated-initcalls.c: .allinit.defs
+ set -e; echo '#include <linux/init.h>' > $@; \
+ sed -n < $< "s,^T ,,p" | sort > .defined.all; \
+ sed -n < $< "s,^U ,,p" | sort > .undefined.all; \
+ join -o "1.2 2.2" .defined.all .undefined.all | sort -u | tsort > .sorted.all; \
+ cut -d ' ' -f 3 < .allinit.defs | sort -u | grep -v -f .sorted.all > .other.all; \
+ cat .other.all >> .sorted.all; \
+ while read obj; do objdump -t $$obj | awk '/F \.initcall\.test/ { print "extern int " $$6 "(void);" }'; done < .other.all >> $@; \
+ echo 'initcall_t generated_initcalls[] = {' >> $@; \
+ while read obj; do objdump -t $$obj | awk '/F \.initcall\.test/ { print $$6 "," }'; done < .other.all >> $@; \
+ echo '0 };' >> $@
+
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+.allinit.defs: $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)
+ rm -f $@; \
+ for s in $(dir $^); do ls -ld $$s; awk "{ print \$$1 \" \" \$$2 \" $$s\" \$$3 }" < $${s}.all_defs >> $@; done
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
@@ -586,6 +603,7 @@ defconfig:
# files removed with 'make clean'
CLEAN_FILES += \
+ init/generated-initcalls.c .allinit.defs .defined.all .undefined.all .other.all .sorted.all \
include/linux/compile.h \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
@@ -647,7 +665,7 @@ clean: archclean
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .\*[._]defs \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
Index: Rules.make
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/Rules.make,v
retrieving revision 1.1.1.17
diff -u -p -r1.1.1.17 Rules.make
--- Rules.make 6 Jul 2002 00:33:37 -0000 1.1.1.17
+++ Rules.make 27 Jul 2002 18:56:39 -0000
@@ -105,9 +105,16 @@ multi-objs-m := $(foreach m, $(multi-use
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
+mod-objs-y := $(filter-out $(subdir-obj-y), $(obj-y))
+real-objs-y := $(foreach m, $(mod-objs-y), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
+modnames := $(foreach m, $(sort $(mod-objs-y) $(objs-m)), $(if $($(m:.o=-objs)),$(foreach mm,$($(m:.o=-objs)),.$(mm).$(m))))
+
+modname = $(*F)
+
+$(multi-objs-y) $(multi-objs-m) : modname = $(patsubst .$@.%,%,$(filter .$@.%,$(modnames)))
+
# Only build module versions for files which are selected to be built
export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m))
@@ -168,6 +175,7 @@ $(addprefix $(MODVERDIR)/,$(export-objs:
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
-DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+ -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname:.o=))) \
$(export_flags)
# Our objects only depend on modversions.h, not on the individual .ver
@@ -248,7 +256,7 @@ endif
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .all_defs
@echo -n
# Compile C sources (.c)
@@ -269,6 +277,7 @@ $(export-objs:.o=.lst): export_flags :
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
-DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+ -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname:.o=))) \
$(export_flags)
quiet_cmd_cc_s_c = CC $(echo_target)
@@ -294,6 +303,17 @@ cmd_cc_lst_c = $(CC) $(c_flags) -g -
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+
+.%.defs: %.o
+ if [ -n "$$(objdump -h $< | egrep '^[ ]*[0-9]+ \.initcall\.test')" ]; then \
+ nm $< | sed -n "s,^[0-9a-f ]*\([TU].*\),\1 $<,p" > $@; \
+ else > $@; fi
+
+$(subdir-y:%=%/.all_defs): sub_dirs
+
+.all_defs: $(mod-objs-y:%.o=.%.defs) $(subdir-y:%=%/.all_defs)
+ cat $(mod-objs-y:%.o=.%.defs) /dev/null > $@; \
+ for s in $(subdir-y); do awk "{ print \$$1 \" \" \$$2 \" $$s/\" \$$3 }" < $$s/.all_defs; done >> $@
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
Index: drivers/ide/main.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/drivers/ide/main.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 main.c
--- drivers/ide/main.c 27 Jul 2002 12:40:01 -0000 1.1.1.7
+++ drivers/ide/main.c 27 Jul 2002 13:19:30 -0000
@@ -1401,12 +1401,6 @@ static int __init ata_module_init(void)
/*
* Initialize all device type driver modules.
*/
-#ifdef CONFIG_BLK_DEV_IDEDISK
- idedisk_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- ide_cdrom_init();
-#endif
#ifdef CONFIG_BLK_DEV_IDETAPE
idetape_init();
#endif
Index: fs/dnotify.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/dnotify.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 dnotify.c
--- fs/dnotify.c 27 Jul 2002 12:34:15 -0000 1.1.1.5
+++ fs/dnotify.c 27 Jul 2002 13:19:30 -0000
@@ -155,4 +155,4 @@ static int __init dnotify_init(void)
return 0;
}
-module_init(dnotify_init)
+fs_initcall(dnotify_init);
Index: fs/fcntl.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/fcntl.c,v
retrieving revision 1.1.1.8
diff -u -p -r1.1.1.8 fcntl.c
--- fs/fcntl.c 27 Jul 2002 12:34:14 -0000 1.1.1.8
+++ fs/fcntl.c 27 Jul 2002 13:19:30 -0000
@@ -568,4 +568,4 @@ static int __init fasync_init(void)
return 0;
}
-module_init(fasync_init)
+fs_initcall(fasync_init);
Index: fs/locks.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/locks.c,v
retrieving revision 1.1.1.9
diff -u -p -r1.1.1.9 locks.c
--- fs/locks.c 27 Jul 2002 12:34:14 -0000 1.1.1.9
+++ fs/locks.c 27 Jul 2002 13:19:30 -0000
@@ -1936,4 +1936,4 @@ static int __init filelock_init(void)
return 0;
}
-module_init(filelock_init)
+fs_initcall(filelock_init);
Index: include/linux/init.h
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/include/linux/init.h,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 init.h
--- include/linux/init.h 13 Jun 2002 00:22:57 -0000 1.1.1.6
+++ include/linux/init.h 27 Jul 2002 13:19:30 -0000
@@ -65,10 +65,16 @@ extern initcall_t __initcall_start, __in
#define arch_initcall(fn) __define_initcall("3",fn)
#define subsys_initcall(fn) __define_initcall("4",fn)
#define fs_initcall(fn) __define_initcall("5",fn)
-#define device_initcall(fn) __define_initcall("6",fn)
-#define late_initcall(fn) __define_initcall("7",fn)
-#define __initcall(fn) device_initcall(fn)
+#define device_initcall(fn) __initcall(fn)
+#define late_initcall(fn) __initcall(fn)
+
+#define __CAT3(a,b,c) a##b##c
+#define _CAT3(a,b,c) __CAT3(a,b,c)
+
+#define __initcall(fn) \
+ int __attribute__((__section__ (".initcall.test"))) _CAT3(fn,_,KBUILD_MODNAME)(void) \
+ { return fn(); }
#define __exitcall(fn) \
static exitcall_t __exitcall_##fn __exit_call = fn
Index: init/main.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/init/main.c,v
retrieving revision 1.1.1.17
diff -u -p -r1.1.1.17 main.c
--- init/main.c 27 Jul 2002 12:34:42 -0000 1.1.1.17
+++ init/main.c 27 Jul 2002 13:19:31 -0000
@@ -464,6 +464,8 @@ asmlinkage void __init start_kernel(void
struct task_struct *child_reaper = &init_task;
+extern initcall_t generated_initcalls[];
+
static void __init do_initcalls(void)
{
initcall_t *call;
@@ -473,6 +475,9 @@ static void __init do_initcalls(void)
(*call)();
call++;
} while (call < &__initcall_end);
+
+ for (call = generated_initcalls; *call; call++)
+ (*call)();
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_tasks();
Index: kernel/sched.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/kernel/sched.c,v
retrieving revision 1.1.1.22
diff -u -p -r1.1.1.22 sched.c
--- kernel/sched.c 27 Jul 2002 12:34:42 -0000 1.1.1.22
+++ kernel/sched.c 27 Jul 2002 15:50:14 -0000
@@ -1910,7 +1910,7 @@ int __init migration_init(void)
return 0;
}
-__initcall(migration_init);
+fs_initcall(migration_init);
#endif
extern void init_timervecs(void);
Index: kernel/softirq.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/kernel/softirq.c,v
retrieving revision 1.1.1.12
diff -u -p -r1.1.1.12 softirq.c
--- kernel/softirq.c 27 Jul 2002 12:34:43 -0000 1.1.1.12
+++ kernel/softirq.c 27 Jul 2002 15:50:14 -0000
@@ -417,4 +417,4 @@ static __init int spawn_ksoftirqd(void)
return 0;
}
-__initcall(spawn_ksoftirqd);
+fs_initcall(spawn_ksoftirqd);
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-27 20:22 [PATCH] automatic initcalls Roman Zippel
@ 2002-07-28 3:31 ` Rusty Russell
2002-07-28 3:51 ` Jeff Garzik
` (3 more replies)
0 siblings, 4 replies; 36+ messages in thread
From: Rusty Russell @ 2002-07-28 3:31 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Kai Germaschewski, torvalds
In message <3D430123.739CA34D@linux-m68k.org> you write:
> - I only look at modules which contain an initcall
> - I only order initcalls of level 6 and 7
You don't seem to handle the ordering of initcalls within a module
though: see net/ipv4/netfilter/ip_conntrack.o for an example of
multiple inits which would be much better as separate initcalls.
The more I play with these magic approaches, the more I prefer an
explicit "Must be done after this" and "must be done before this":
otherwise we're going to need to keep adding new levels as we discover
something that doesn't fit in the magic 7.
Especially since you don't cover any of the really interesting cases.
Maybe if you could slowly extend it to cover the rest? (Hah, I
know!).
> +init/generated-initcalls.c: .allinit.defs
> + set -e; echo '#include <linux/init.h>' > $@; \
> + sed -n < $< "s,^T ,,p" | sort > .defined.all; \
I think you mean something like:
sed -n "s,^T ,,p" < $<
> -__initcall(spawn_ksoftirqd);
> +fs_initcall(spawn_ksoftirqd);
See, this is exacly the kind of thing that makes me doubt that the
current "magic 7 initcall levels" are useful in the long term 8(
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:31 ` Rusty Russell
@ 2002-07-28 3:51 ` Jeff Garzik
2002-07-28 4:47 ` Linus Torvalds
2002-07-29 8:39 ` Ingo Oeser
2002-07-28 12:18 ` Roman Zippel
` (2 subsequent siblings)
3 siblings, 2 replies; 36+ messages in thread
From: Jeff Garzik @ 2002-07-28 3:51 UTC (permalink / raw)
To: Rusty Russell; +Cc: Roman Zippel, linux-kernel, Kai Germaschewski, torvalds
Rusty Russell wrote:
> The more I play with these magic approaches, the more I prefer an
> explicit "Must be done after this" and "must be done before this":
> otherwise we're going to need to keep adding new levels as we discover
> something that doesn't fit in the magic 7.
I've always preferred a system where one simply lists dependencies [as
you describe above], and some program actually does the hard work of
chasing down all the initcall dependency checking and ordering.
Linus has traditionally poo-pooed this so I haven't put any work towards
it... but I still think it's a good idea, and something we will
eventually need as our system grows more complex. If someone stood up
and did the work, it should be pretty easy to generate a human-readable
list of dependencies so we can check the ordering and make sure it's
getting things right.
I wonder if there is some nifty ld feature I'm missing, that could do
this for us...
Jeff
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:51 ` Jeff Garzik
@ 2002-07-28 4:47 ` Linus Torvalds
2002-07-28 8:50 ` Keith Adamson
` (2 more replies)
2002-07-29 8:39 ` Ingo Oeser
1 sibling, 3 replies; 36+ messages in thread
From: Linus Torvalds @ 2002-07-28 4:47 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Rusty Russell, Roman Zippel, linux-kernel, Kai Germaschewski
On Sat, 27 Jul 2002, Jeff Garzik wrote:
>
> I've always preferred a system where one simply lists dependencies [as
> you describe above], and some program actually does the hard work of
> chasing down all the initcall dependency checking and ordering.
>
> Linus has traditionally poo-pooed this so I haven't put any work towards
> it...
I don't hate the notion, but at the same time every time it comes up I
feel that there are reasonably simple ways to just avoid the ordering
problems.
Rusty had a script, but somebody complained about the speed of it. I
haven't looked at it myself.
Linus
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 4:47 ` Linus Torvalds
@ 2002-07-28 8:50 ` Keith Adamson
2002-07-28 18:59 ` Oliver Xymoron
2002-07-29 23:39 ` Rusty Russell
2 siblings, 0 replies; 36+ messages in thread
From: Keith Adamson @ 2002-07-28 8:50 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]
On Sun, 2002-07-28 at 00:47, Linus Torvalds wrote:
>
>
> On Sat, 27 Jul 2002, Jeff Garzik wrote:
> >
> > I've always preferred a system where one simply lists dependencies [as
> > you describe above], and some program actually does the hard work of
> > chasing down all the initcall dependency checking and ordering.
> >
> > Linus has traditionally poo-pooed this so I haven't put any work towards
> > it...
>
> I don't hate the notion, but at the same time every time it comes up I
> feel that there are reasonably simple ways to just avoid the ordering
> problems.
>
> Rusty had a script, but somebody complained about the speed of it. I
> haven't looked at it myself.
>
> Linus
There is a relatively simple and fast recursive algorithm I've used
before to generating a sequence from a dependency list.
For initcall sequence it would be something like this (bash scripts
attached);
Dependency database: dependency_list_database
Main programs: make_initcall_seqence.sh
Recursive routine: generate_initcall.sh
Output sequence: initcall_sequence
See attached files.
Normally I have error checking for bad dependencies (you can get into a
infinite recursive loop if for instance "foo1" needs "foo2" and also
"foo2" needs "foo1") ... but I didn't do it to keep the algorithm more
understandable.
Keith
[-- Attachment #2: make_initcall_seqence.sh --]
[-- Type: text/x-sh, Size: 618 bytes --]
#!/bin/bash
#
# make_initcall_seqence.sh - generate initcall sequence, file
# "initcall_sequence", from an initcall
# dependency list database, file
# "dependency_list_database"
#
# A random list of initcalls (will sequence them acording to the
# dependency database
initcall_list=$(sed 's,:.*$,,' dependency_list_database)
#
# Initialize the initcall_sequence file
rm -f initcall_sequence
touch initcall_sequence
#
# build the initcall_sequence file
for name in $initcall_list
do
generate_initcall.sh $name
done
[-- Attachment #3: generate_initcall.sh --]
[-- Type: text/x-sh, Size: 1372 bytes --]
#!/bin/bash
#
# generate_initcall.sh - Insert initcall into the "initcall_sequence"
# file in correct sequence
#
# First arg is the initcall
initcall=$1
#
# Get dependency initcall list for this initcall from the dependency
# database
dependency_initcall_list=$(
grep '^'$initcall'[ :]' dependency_list_database | \
sed 's,^.*:,,'
)
#
# function to find a missing initcall in initcall_sequence
function find_missing_initcall()
{
need_initcall=""
for name in $dependency_initcall_list
do
# test if initcall not done in initcall_sequence
if [ "$(grep '^'$name'$' initcall_sequence)" = "" ]
then
# return needed initcall
need_initcall=$name
break
fi
done
}
#
# generate missing initcalls that this initcall needs done first
#
find_missing_initcall
while [ -n "$need_initcall" ] # loop while adding missing initcalls
do
generate_initcall.sh $need_initcall # NOTE THE RECURSIVE CALL
find_missing_initcall
done
#
# Finally add this initcall to initcall_sequence (if missing)
if [ "$(grep '^'$initcall'$' initcall_sequence)" = "" ]
then
echo $initcall >> initcall_sequence
fi
[-- Attachment #4: dependency_list_database --]
[-- Type: text/plain, Size: 71 bytes --]
foo1 : foo2 foo3
foo2 : foo5
foo3 : foo2 foo4
foo4 :
foo5 : foo4
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:31 ` Rusty Russell
2002-07-28 3:51 ` Jeff Garzik
@ 2002-07-28 12:18 ` Roman Zippel
2002-07-29 23:46 ` Rusty Russell
2002-07-28 21:59 ` [PATCH] automatic initcalls Kai Germaschewski
2002-07-29 18:56 ` Patrick Mochel
3 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-07-28 12:18 UTC (permalink / raw)
To: Rusty Russell; +Cc: linux-kernel, Kai Germaschewski, Linus Torvalds
Hi,
On Sun, 28 Jul 2002, Rusty Russell wrote:
> > - I only look at modules which contain an initcall
> > - I only order initcalls of level 6 and 7
>
> You don't seem to handle the ordering of initcalls within a module
> though: see net/ipv4/netfilter/ip_conntrack.o for an example of
> multiple inits which would be much better as separate initcalls.
Actually I'm most interested in ordering "module_init()" and you can have
only one of them per module or how do you want to implement multiple
initcalls per module?
> Especially since you don't cover any of the really interesting cases.
> Maybe if you could slowly extend it to cover the rest? (Hah, I
> know!).
I wouldn't mind if the remaining initcalls are converted to explicit
dependencies, but it's possible to sort automatically everything that can
be built as modules.
> > +init/generated-initcalls.c: .allinit.defs
> > + set -e; echo '#include <linux/init.h>' > $@; \
> > + sed -n < $< "s,^T ,,p" | sort > .defined.all; \
>
> I think you mean something like:
>
> sed -n "s,^T ,,p" < $<
Isn't that the same?
bye, Roman
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 4:47 ` Linus Torvalds
2002-07-28 8:50 ` Keith Adamson
@ 2002-07-28 18:59 ` Oliver Xymoron
2002-07-29 23:39 ` Rusty Russell
2 siblings, 0 replies; 36+ messages in thread
From: Oliver Xymoron @ 2002-07-28 18:59 UTC (permalink / raw)
To: Linus Torvalds
Cc: Jeff Garzik, Rusty Russell, Roman Zippel, linux-kernel,
Kai Germaschewski
On Sat, 27 Jul 2002, Linus Torvalds wrote:
> On Sat, 27 Jul 2002, Jeff Garzik wrote:
> >
> > I've always preferred a system where one simply lists dependencies [as
> > you describe above], and some program actually does the hard work of
> > chasing down all the initcall dependency checking and ordering.
> >
> > Linus has traditionally poo-pooed this so I haven't put any work towards
> > it...
>
> I don't hate the notion, but at the same time every time it comes up I
> feel that there are reasonably simple ways to just avoid the ordering
> problems.
The 'simple ways' are only simpler because they're taking advantage of
pre-existing (and undocumented) implicit ordering. The explicit
dependencies are probably less complex on the whole as it lets you take
out a ton of per-subsystem conditional cruft and replace it with a couple
lines of dependency info.
Given that sizeof(dependency info)==sizeof(missing documentation of
dependencies), it's clear that sizeof(dependency info + support + script)
< sizeof(current ordering code + conditional cruft + missing
documentation).
--
"Love the dolphins," she advised him. "Write by W.A.S.T.E.."
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:31 ` Rusty Russell
2002-07-28 3:51 ` Jeff Garzik
2002-07-28 12:18 ` Roman Zippel
@ 2002-07-28 21:59 ` Kai Germaschewski
2002-07-29 18:56 ` Patrick Mochel
3 siblings, 0 replies; 36+ messages in thread
From: Kai Germaschewski @ 2002-07-28 21:59 UTC (permalink / raw)
To: Rusty Russell; +Cc: Roman Zippel, linux-kernel, torvalds
On Sun, 28 Jul 2002, Rusty Russell wrote:
> In message <3D430123.739CA34D@linux-m68k.org> you write:
> > - I only look at modules which contain an initcall
> > - I only order initcalls of level 6 and 7
>
> You don't seem to handle the ordering of initcalls within a module
> though: see net/ipv4/netfilter/ip_conntrack.o for an example of
> multiple inits which would be much better as separate initcalls.
I'm not at all familiar with this code, but traditionally there is only
one initcall per module - extending this to multiple initcalls with
automated unwinding if one of those fails may be something to look into,
but I don't think it has much to do with the current discussion (I doubt
your patch does the unwinding, does it?)
> The more I play with these magic approaches, the more I prefer an
> explicit "Must be done after this" and "must be done before this":
> otherwise we're going to need to keep adding new levels as we discover
> something that doesn't fit in the magic 7.
>
> Especially since you don't cover any of the really interesting cases.
> Maybe if you could slowly extend it to cover the rest? (Hah, I
> know!).
I think when I commented on your initial patch, I said that I would make
sense to use the existing ordering information where available, but it
surely doesn't solve all the world's problems, so your patch would help a
lot in cleaning up the ordering of the early initcalls of not modularized
parts of the kernel.
For modules, it's obvious that we cannot insmod a module unless it's
unresolved symbols can be resolved, i.e. the code which provides them has
to be compiled-in or a module providing them has been loaded before. This
is also the only way to determine the order of loading modules we have, so
we guarantee that once all unresolved symbols are made available, all
necessary initializations have run - most people probably don't think of
it this way, because it comes natural anyway.
My point was that I don't think it's necessarily a good idea to duplicate
this info - hisax.o (an ISDN hardware driver) needs "register_isdn()",
which is provided by isdn.o. Insmoding isdn.o will of course also run the
necessary initializations for making register_isdn() ready to be called
from driver modules. It has to remain this way, since otherwise insmoding
modules in the wrong order would crash the kernel. Now, in your scheme you
would add an dependency like
__initcall(hisax_init, initcall_after(isdn_init))
which duplicates this info. Which, as all duplicated info is redundant and
has the potential for getting out of sync, different behavior for built-in
vs. modular, etc.
On the other hand, we have complicated ordering during init, like
(probably wrong as I put it, but you get the picture):
pci_driver_init()
pci_pcibios_init()
pci_direct_init()
pci_legacy_init()
acpi_pci_init()
pci_init()
These parts are not modularized, so the argument above doesn't help. Here,
I think it would be a great improvement to be able to give dependencies on
what has to be run when explicitly.
So the ideal solution would, IMO, look like:
Replace the __initcall levels by two constructs:
o __initcall(foo_init, init_after/...)
o module_init()
The __initcalls are called first, in the order explicitly given. Only
then, the functions declared as module_init() would get called, in an
order determined by the dependencies on exported symbols - i.e. that would
be comparable with compiling them as modules and insmoding them in just
this order.
I didn't have the time to look at the patches in depth yet, but it looks
like we've got the two pieces and just have to put them together.
--Kai
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:51 ` Jeff Garzik
2002-07-28 4:47 ` Linus Torvalds
@ 2002-07-29 8:39 ` Ingo Oeser
2002-07-30 2:49 ` Keith Adamson
1 sibling, 1 reply; 36+ messages in thread
From: Ingo Oeser @ 2002-07-29 8:39 UTC (permalink / raw)
To: Jeff Garzik
Cc: Rusty Russell, Roman Zippel, linux-kernel, Kai Germaschewski,
torvalds
On Sat, Jul 27, 2002 at 11:51:32PM -0400, Jeff Garzik wrote:
> I've always preferred a system where one simply lists dependencies [as
> you describe above], and some program actually does the hard work of
> chasing down all the initcall dependency checking and ordering.
So we just need to build a directed graph, detect edges without
existing nodes (someone changed the initcall, we depend on) and
cycles (someone messed up the ordering) as errors, sort the
resulting graph toplogically and dump it as a sequence.
This is no rocket science and we have two tools, which does this
all for us (make and tsort, which create a warning for both cases).
The hard part is to CREATE all the dependencies and check and
double check them with the maintainers.
Regards
Ingo Oeser
--
Science is what we can tell a computer. Art is everything else. --- D.E.Knuth
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 3:31 ` Rusty Russell
` (2 preceding siblings ...)
2002-07-28 21:59 ` [PATCH] automatic initcalls Kai Germaschewski
@ 2002-07-29 18:56 ` Patrick Mochel
2002-07-29 20:14 ` Roman Zippel
3 siblings, 1 reply; 36+ messages in thread
From: Patrick Mochel @ 2002-07-29 18:56 UTC (permalink / raw)
To: Rusty Russell; +Cc: Roman Zippel, linux-kernel, Kai Germaschewski, torvalds
> > -__initcall(spawn_ksoftirqd);
> > +fs_initcall(spawn_ksoftirqd);
>
> See, this is exacly the kind of thing that makes me doubt that the
> current "magic 7 initcall levels" are useful in the long term 8(
I agree that that is abusing the interface. WTF does spawn_ksoftirqd have
to do with filesystems?
The purpose of the initcall levels in the first place was to start
removing the ugly conditional calls in init/main.c I looked at what was
being called, and came up with names to describe what was being done at
each phase. There happened to be seven of them.
I knew from the start that people would feel that they were more important
that others, and leapfrog their initcalls before everyone else. We're
egotistical; that's what we do. But remember, just because it's there,
doesn't mean you have to use it.
That said, it's been a while since I've really looked at it. I favor a
mechanism for getting the ordering right. I don't really like having to
specify the dependencies in the definitions; I think it's kinda ugly and
wonder if there is an automatic way to resolve them. I don't have any
ideas, nor the time to play with it, so it remains still just a pipe
dream...
-pat
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-29 18:56 ` Patrick Mochel
@ 2002-07-29 20:14 ` Roman Zippel
0 siblings, 0 replies; 36+ messages in thread
From: Roman Zippel @ 2002-07-29 20:14 UTC (permalink / raw)
To: Patrick Mochel
Cc: Rusty Russell, linux-kernel, Kai Germaschewski, Linus Torvalds
Hi,
On Mon, 29 Jul 2002, Patrick Mochel wrote:
> > > -__initcall(spawn_ksoftirqd);
> > > +fs_initcall(spawn_ksoftirqd);
> >
> > See, this is exacly the kind of thing that makes me doubt that the
> > current "magic 7 initcall levels" are useful in the long term 8(
>
> I agree that that is abusing the interface. WTF does spawn_ksoftirqd have
> to do with filesystems?
Above is just a hack to get it working, I only moved it one level up,
instead of spending too much time on figuring out the complete
dependencies.
> The purpose of the initcall levels in the first place was to start
> removing the ugly conditional calls in init/main.c I looked at what was
> being called, and came up with names to describe what was being done at
> each phase. There happened to be seven of them.
I think we should separate module initialization from this, as these can
be automatically ordered, what the posted patch demonstrates.
The initcall mechanism would then only be needed to initialize core kernel
services, which can't be build as module.
I'm only interrested to get the module initialization right, because
otherwise I get problems with the new module interface. I want to avoid
to include an explicit ordering, but currently some modules make use of
that *_initcall is mapped to module_init if compiled as module (e.g. usb
or pcmcia).
bye, Roman
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 4:47 ` Linus Torvalds
2002-07-28 8:50 ` Keith Adamson
2002-07-28 18:59 ` Oliver Xymoron
@ 2002-07-29 23:39 ` Rusty Russell
2 siblings, 0 replies; 36+ messages in thread
From: Rusty Russell @ 2002-07-29 23:39 UTC (permalink / raw)
To: Linus Torvalds
Cc: Rusty Russell, Roman Zippel, linux-kernel, Kai Germaschewski
In message <Pine.LNX.4.44.0207272145050.6125-100000@home.transmeta.com> you wri
te:
>
>
> On Sat, 27 Jul 2002, Jeff Garzik wrote:
> >
> > I've always preferred a system where one simply lists dependencies [as
> > you describe above], and some program actually does the hard work of
> > chasing down all the initcall dependency checking and ordering.
> >
> > Linus has traditionally poo-pooed this so I haven't put any work towards
> > it...
>
> I don't hate the notion, but at the same time every time it comes up I
> feel that there are reasonably simple ways to just avoid the ordering
> problems.
I think that the best hope is a combination of Roman's module depends
work (based on Kai's "everything which is a module is trivial", and
Stephen and my first depends hack) and explicit depends.
Linkage ordering doesn't work in general, for things like "I want to
be initialized before the non-boot cpus have come up", but for
non-core code it's simple.
> Rusty had a script, but somebody complained about the speed of it. I
> haven't looked at it myself.
Yes, it'll slow the build by a few seconds: but if the linker ever
decides not to preserve ordering, we'll need it. My original shell
script is suboptimal but we *don't* want the kernel build relying on
libbfd.
Roman and I will come up with something and send it to you later this
week.
Thanks!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-28 12:18 ` Roman Zippel
@ 2002-07-29 23:46 ` Rusty Russell
2002-07-30 23:04 ` [PATCH] automatic module_init ordering Roman Zippel
0 siblings, 1 reply; 36+ messages in thread
From: Rusty Russell @ 2002-07-29 23:46 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Kai Germaschewski
In message <Pine.LNX.4.44.0207281358070.28515-100000@serv> you write:
> Hi,
>
> On Sun, 28 Jul 2002, Rusty Russell wrote:
>
> > > - I only look at modules which contain an initcall
> > > - I only order initcalls of level 6 and 7
> >
> > You don't seem to handle the ordering of initcalls within a module
> > though: see net/ipv4/netfilter/ip_conntrack.o for an example of
> > multiple inits which would be much better as separate initcalls.
>
> Actually I'm most interested in ordering "module_init()" and you can have
> only one of them per module or how do you want to implement multiple
> initcalls per module?
Sorry, you are right. That was a brain fart.
> > Especially since you don't cover any of the really interesting cases.
> > Maybe if you could slowly extend it to cover the rest? (Hah, I
> > know!).
>
> I wouldn't mind if the remaining initcalls are converted to explicit
> dependencies, but it's possible to sort automatically everything that can
> be built as modules.
Yes, I think we should do this: merge the two together. You seem to
be in a coding frenzy: want to do the first cut?
I'll probably change my initdepends section format to make it shorter
and easier to parse. But that change should be independent.
> > > +init/generated-initcalls.c: .allinit.defs
> > > + set -e; echo '#include <linux/init.h>' > $@; \
> > > + sed -n < $< "s,^T ,,p" | sort > .defined.all; \
> >
> > I think you mean something like:
> >
> > sed -n "s,^T ,,p" < $<
>
> Isn't that the same?
Argh, not my day, clearly. Let's pretend I didn't send that mail,
shall we?
Cheers,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-29 8:39 ` Ingo Oeser
@ 2002-07-30 2:49 ` Keith Adamson
2002-07-30 2:51 ` Keith Adamson
0 siblings, 1 reply; 36+ messages in thread
From: Keith Adamson @ 2002-07-30 2:49 UTC (permalink / raw)
To: Ingo Oeser
Cc: Jeff Garzik, Rusty Russell, Roman Zippel, linux-kernel,
Kai Germaschewski, torvalds
On Mon, 2002-07-29 at 04:39, Ingo Oeser wrote:
> On Sat, Jul 27, 2002 at 11:51:32PM -0400, Jeff Garzik wrote:
> > I've always preferred a system where one simply lists dependencies [as
> > you describe above], and some program actually does the hard work of
> > chasing down all the initcall dependency checking and ordering.
>
> So we just need to build a directed graph, detect edges without
> existing nodes (someone changed the initcall, we depend on) and
> cycles (someone messed up the ordering) as errors, sort the
> resulting graph toplogically and dump it as a sequence.
>
> This is no rocket science and we have two tools, which does this
> all for us (make and tsort, which create a warning for both cases).
>
> The hard part is to CREATE all the dependencies and check and
> double check them with the maintainers.
>
I definitely agree the easy part is the algorithm and the hard part is
creating the dependency list. For instance, attached is a small
algorithm that does the initcall sequencing at run time.
The API is is simple, you just register your initcall with a list of
critical initcalls you need to be run before yours (not all, just the
ones you definitely need to be run first). Then the ordering of the all
the initcalls are sequenced at run time. This way you don't have to
worry about link ordering or code ordering of your initcalls during
make/compile/link. All initcall ordering is done during boot.
This really frees you from module inter-dependencies because is doesn't
mater in what order you register you initcalls. You only need register
them with a list the critical modules that need to be initialized before
yours.
The API also provides that you can register more than one initcall for
your module with a different set of critical modules that must be run
first.
This should be relative easy to add to the kernel, as you don't have to
modify any of the existing initcalls. You do need to remove all
existing calls to them and register them instead with the new API.
Untar and "cd init; cc *.c; ./a.out"
Four example modules register their initcalls, "foo1, foo2, foo3, foo4",
and then the main routine sequences them at run time.
Regards, Keith
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic initcalls
2002-07-30 2:49 ` Keith Adamson
@ 2002-07-30 2:51 ` Keith Adamson
0 siblings, 0 replies; 36+ messages in thread
From: Keith Adamson @ 2002-07-30 2:51 UTC (permalink / raw)
To: Keith Adamson
Cc: Ingo Oeser, Jeff Garzik, Rusty Russell, Roman Zippel,
linux-kernel, Kai Germaschewski, torvalds
[-- Attachment #1: Type: text/plain, Size: 2387 bytes --]
On Mon, 2002-07-29 at 22:49, Keith Adamson wrote:
> On Mon, 2002-07-29 at 04:39, Ingo Oeser wrote:
> > On Sat, Jul 27, 2002 at 11:51:32PM -0400, Jeff Garzik wrote:
> > > I've always preferred a system where one simply lists dependencies [as
> > > you describe above], and some program actually does the hard work of
> > > chasing down all the initcall dependency checking and ordering.
> >
> > So we just need to build a directed graph, detect edges without
> > existing nodes (someone changed the initcall, we depend on) and
> > cycles (someone messed up the ordering) as errors, sort the
> > resulting graph toplogically and dump it as a sequence.
> >
> > This is no rocket science and we have two tools, which does this
> > all for us (make and tsort, which create a warning for both cases).
> >
> > The hard part is to CREATE all the dependencies and check and
> > double check them with the maintainers.
> >
>
> I definitely agree the easy part is the algorithm and the hard part is
> creating the dependency list. For instance, attached is a small
> algorithm that does the initcall sequencing at run time.
>
> The API is is simple, you just register your initcall with a list of
> critical initcalls you need to be run before yours (not all, just the
> ones you definitely need to be run first). Then the ordering of the all
> the initcalls are sequenced at run time. This way you don't have to
> worry about link ordering or code ordering of your initcalls during
> make/compile/link. All initcall ordering is done during boot.
>
> This really frees you from module inter-dependencies because is doesn't
> mater in what order you register you initcalls. You only need register
> them with a list the critical modules that need to be initialized before
> yours.
>
> The API also provides that you can register more than one initcall for
> your module with a different set of critical modules that must be run
> first.
>
> This should be relative easy to add to the kernel, as you don't have to
> modify any of the existing initcalls. You do need to remove all
> existing calls to them and register them instead with the new API.
>
> Untar and "cd init; cc *.c; ./a.out"
>
> Four example modules register their initcalls, "foo1, foo2, foo3, foo4",
> and then the main routine sequences them at run time.
>
> Regards, Keith
>
>
Forgot the attachment :)
[-- Attachment #2: init_020729.tar --]
[-- Type: application/x-tar, Size: 10240 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH] automatic module_init ordering
2002-07-29 23:46 ` Rusty Russell
@ 2002-07-30 23:04 ` Roman Zippel
2002-07-31 2:33 ` Kai Germaschewski
0 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-07-30 23:04 UTC (permalink / raw)
To: Rusty Russell; +Cc: linux-kernel, Kai Germaschewski
[-- Attachment #1: Type: text/plain, Size: 347 bytes --]
Hi,
Rusty Russell wrote:
> Yes, I think we should do this: merge the two together. You seem to
> be in a coding frenzy: want to do the first cut?
I attached a new version, that only orders module_init(). I did some
small compile performance tests and I could only see a few seconds
difference, so the overhead should be negligible.
bye, Roman
[-- Attachment #2: initcall.diff --]
[-- Type: text/plain, Size: 9187 bytes --]
Index: Makefile
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/Makefile,v
retrieving revision 1.1.1.30
diff -u -p -r1.1.1.30 Makefile
--- Makefile 27 Jul 2002 12:34:13 -0000 1.1.1.30
+++ Makefile 30 Jul 2002 21:57:02 -0000
@@ -268,6 +268,7 @@ cmd_link_vmlinux = $(LD) $(LDFLAGS) $(LD
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -284,9 +285,30 @@ define rule_link_vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+init/generated-initcalls.c: .allbuiltin_mods
+ set -e; \
+ while read obj; do $(NM) $$obj | sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $$obj,p"; done < $< | \
+ awk '/^U/ { print $$2 " " $$3 | "sort -u > .undefined.tmp" }; \
+ /^[TD]/ { print $$2 " " $$3 | "sort -u > .defined.tmp" }'; \
+ join -o "1.2 2.2" .defined.tmp .undefined.tmp | sort -u | tsort > .sorted.tmp; \
+ grep -v -f .sorted.tmp < $< > .other.tmp; \
+ cat .other.tmp >> .sorted.tmp; \
+ while read obj; do \
+ call=$$($(OBJDUMP) -t $$obj | awk '/F \.initcall\.module/ { print $$6 }' ); \
+ defs="$$defs extern int $$call(void);"; arr="$$arr $$call,"; \
+ done < .sorted.tmp; \
+ echo "#include <linux/init.h>" > $@; \
+ echo $$defs >> $@; \
+ echo 'initcall_t generated_initcalls[] = {' >> $@; \
+ echo $$arr >> $@; \
+ echo '0 };' >> $@
+
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+.allbuiltin_mods: $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)
+ for s in $(dir $^); do sed "s,^,$$s," < $${s}.builtin_mods; done > $@
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
@@ -586,6 +608,7 @@ defconfig:
# files removed with 'make clean'
CLEAN_FILES += \
+ init/generated-initcalls.c .allbuiltin_mods \
include/linux/compile.h \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
@@ -647,7 +670,7 @@ clean: archclean
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .builtin_mods \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
Index: Rules.make
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/Rules.make,v
retrieving revision 1.1.1.17
diff -u -p -r1.1.1.17 Rules.make
--- Rules.make 6 Jul 2002 00:33:37 -0000 1.1.1.17
+++ Rules.make 30 Jul 2002 18:37:47 -0000
@@ -105,9 +105,16 @@ multi-objs-m := $(foreach m, $(multi-use
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
+mod-objs-y := $(filter-out $(subdir-obj-y), $(obj-y))
+real-objs-y := $(foreach m, $(mod-objs-y), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
+modnames := $(foreach m, $(sort $(mod-objs-y) $(objs-m)), $(if $($(m:.o=-objs)),$(foreach mm,$($(m:.o=-objs)),.$(mm).$(m))))
+
+modname = $(*F)
+
+$(multi-objs-y) $(multi-objs-m) : modname = $(patsubst .$@.%,%,$(filter .$@.%,$(modnames)))
+
# Only build module versions for files which are selected to be built
export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m))
@@ -168,6 +175,7 @@ $(addprefix $(MODVERDIR)/,$(export-objs:
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
-DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+ -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname:.o=))) \
$(export_flags)
# Our objects only depend on modversions.h, not on the individual .ver
@@ -248,7 +256,7 @@ endif
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .builtin_mods
@echo -n
# Compile C sources (.c)
@@ -269,6 +277,7 @@ $(export-objs:.o=.lst): export_flags :
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
-DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
+ -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname:.o=))) \
$(export_flags)
quiet_cmd_cc_s_c = CC $(echo_target)
@@ -294,6 +303,14 @@ cmd_cc_lst_c = $(CC) $(c_flags) -g -
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+
+$(subdir-y:%=%/.builtin_mods): sub_dirs
+
+.builtin_mods: $(mod-objs-y) $(subdir-y:%=%/.builtin_mods)
+ for o in $(mod-objs-y); do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then echo $$o; fi \
+ done > $@; \
+ for s in $(subdir-y); do sed "s,^,$$s/," < $$s/.builtin_mods; done >> $@
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
Index: drivers/ide/main.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/drivers/ide/main.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 main.c
--- drivers/ide/main.c 27 Jul 2002 12:40:01 -0000 1.1.1.7
+++ drivers/ide/main.c 30 Jul 2002 18:37:47 -0000
@@ -1397,23 +1397,6 @@ static int __init ata_module_init(void)
}
# endif
#endif
-
- /*
- * Initialize all device type driver modules.
- */
-#ifdef CONFIG_BLK_DEV_IDEDISK
- idedisk_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- ide_cdrom_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDEFLOPPY
- idefloppy_init();
-#endif
-
initializing = 0;
register_reboot_notifier(&ata_notifier);
Index: fs/dnotify.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/dnotify.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 dnotify.c
--- fs/dnotify.c 27 Jul 2002 12:34:15 -0000 1.1.1.5
+++ fs/dnotify.c 30 Jul 2002 18:37:47 -0000
@@ -155,4 +155,4 @@ static int __init dnotify_init(void)
return 0;
}
-module_init(dnotify_init)
+fs_initcall(dnotify_init);
Index: fs/fcntl.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/fcntl.c,v
retrieving revision 1.1.1.8
diff -u -p -r1.1.1.8 fcntl.c
--- fs/fcntl.c 27 Jul 2002 12:34:14 -0000 1.1.1.8
+++ fs/fcntl.c 30 Jul 2002 18:37:47 -0000
@@ -568,4 +568,4 @@ static int __init fasync_init(void)
return 0;
}
-module_init(fasync_init)
+fs_initcall(fasync_init);
Index: fs/locks.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/fs/locks.c,v
retrieving revision 1.1.1.9
diff -u -p -r1.1.1.9 locks.c
--- fs/locks.c 27 Jul 2002 12:34:14 -0000 1.1.1.9
+++ fs/locks.c 30 Jul 2002 18:37:47 -0000
@@ -1936,4 +1936,4 @@ static int __init filelock_init(void)
return 0;
}
-module_init(filelock_init)
+fs_initcall(filelock_init);
Index: include/linux/init.h
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/include/linux/init.h,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 init.h
--- include/linux/init.h 13 Jun 2002 00:22:57 -0000 1.1.1.6
+++ include/linux/init.h 30 Jul 2002 18:37:47 -0000
@@ -106,6 +106,9 @@ extern struct kernel_param __setup_start
#define __FINIT .previous
#define __INITDATA .section ".data.init","aw"
+#define ___concat(a,b) a##b
+#define __concat(a,b) ___concat(a,b)
+
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -116,7 +119,10 @@ extern struct kernel_param __setup_start
* routine with init_module() which is used by insmod and
* modprobe when the driver is used as a module.
*/
-#define module_init(x) __initcall(x);
+#define module_init(x) \
+int __attribute__((__section__ (".initcall.module"))) \
+__concat(init_module_,KBUILD_MODNAME)(void) \
+{ return x(); }
/**
* module_exit() - driver exit entry point
Index: kernel/module.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.5/kernel/module.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 module.c
--- kernel/module.c 14 Apr 2002 20:01:36 -0000 1.1.1.3
+++ kernel/module.c 30 Jul 2002 22:23:53 -0000
@@ -252,6 +252,19 @@ void __init init_modules(void)
arch_init_modules(&kernel_module);
}
+extern initcall_t generated_initcalls[];
+
+static int __init init_builtin_modules(void)
+{
+ initcall_t *call;
+
+ for (call = generated_initcalls; *call; call++)
+ (*call)();
+ return 0;
+}
+
+device_initcall(init_builtin_modules);
+
/*
* Copy the name of a module from user space.
*/
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-07-30 23:04 ` [PATCH] automatic module_init ordering Roman Zippel
@ 2002-07-31 2:33 ` Kai Germaschewski
2002-07-31 3:26 ` Rusty Russell
0 siblings, 1 reply; 36+ messages in thread
From: Kai Germaschewski @ 2002-07-31 2:33 UTC (permalink / raw)
To: Roman Zippel; +Cc: Rusty Russell, linux-kernel
On Wed, 31 Jul 2002, Roman Zippel wrote:
> Hi,
>
> Rusty Russell wrote:
>
> > Yes, I think we should do this: merge the two together. You seem to
> > be in a coding frenzy: want to do the first cut?
>
> I attached a new version, that only orders module_init(). I did some
> small compile performance tests and I could only see a few seconds
> difference, so the overhead should be negligible.
Okay, here's a suggestion to slightly reorganize the KBUILD_MODNAME
part in Rules.make.
- Some sreorganization of the c_flags since they're needed for
generating modversions (.ver) and compiling
- Use the right KBUILD_MODNAME also when the user just wants a .i/.s/.lst
file for debugging and also when generating modversions
- It looks like with your current approach you can't have a ',' or '-' in
KBUILD_MODNAME - however, that means that KBUILD_MODNAME is not quite
right for passing module parameters for built-in modules on the command
line, it would be confusing to pass parameters for ide-cd as
ide_cd.foo=whatever. So that part could use a little more thought.
- If you think your module_names trick makes a noticable difference, feel
free to re-add it.
- It's possible that objects are linked into more than one module - I
suppose this shouldn't be a problem, since these objects hopefully
don't have a module_init() nor do they export symbols. Not sure if your
patch did handle this.
--Kai
===== Rules.make 1.68 vs edited =====
--- 1.68/Rules.make Mon Jul 29 14:55:41 2002
+++ edited/Rules.make Tue Jul 30 21:27:46 2002
@@ -95,11 +95,15 @@
multi-used-y := $(filter-out $(list-multi),$(__multi-used-y))
multi-used-m := $(filter-out $(list-multi),$(__multi-used-m))
+multi-used := $(multi-used-y) $(multi-used-m)
+
# Build list of the parts of our composite objects, our composite
# objects depend on those (obviously)
multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)))
multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)))
+multi-objs := $(multi-objs-y) $(multi-objs-m)
+
# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
# in the local directory
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
@@ -115,6 +119,23 @@
# contain a comma
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
+# These flags are needed for modversions and compiling, so we define them here
+# already
+# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
+# end up in (or would, if it gets compiled in)
+# Note: It's possible that one object gets potentially linked into more
+# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
+# where foo and bar are the name of the modules.
+basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
+modname_flags = -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))
+c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+ $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+ $(basename_flags) $(modname_flags) $(export_flags)
+
+# Finds the multi-part object the current object will be linked into
+modname-multi = $(subst $(space),_,$(strip $(foreach m,$(multi-used),\
+ $(if $(filter $(*F).o,$($(m:.o=-objs))),$(m:.o=)))))
+
# We're called for one of three purposes:
# o fastdep: build module version files (.ver) for $(export-objs) in
# the current directory
@@ -164,11 +185,10 @@
$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL)
$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE)
$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__
+# Default for not multi-part modules
+modname = $(*F)
-c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
- $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
- -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
- $(export_flags)
+$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi)
# Our objects only depend on modversions.h, not on the individual .ver
# files (fix-dep filters them), so touch modversions.h if any of the .ver
@@ -259,6 +279,7 @@
$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
$(export-objs) : export_flags := $(EXPORT_FLAGS)
@@ -266,10 +287,13 @@
$(export-objs:.o=.s) : export_flags := $(EXPORT_FLAGS)
$(export-objs:.o=.lst): export_flags := $(EXPORT_FLAGS)
-c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
- $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
- -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
- $(export_flags)
+# Default for not multi-part modules
+modname = $(*F)
+
+$(multi-objs) : modname = $(modname-multi)
+$(multi-objs:.o=.i) : modname = $(modname-multi)
+$(multi-objs:.o=.s) : modname = $(modname-multi)
+$(multi-objs:.o=.lst) : modname = $(modname-multi)
quiet_cmd_cc_s_c = CC $(echo_target)
cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-07-31 2:33 ` Kai Germaschewski
@ 2002-07-31 3:26 ` Rusty Russell
2002-07-31 17:06 ` Kai Germaschewski
0 siblings, 1 reply; 36+ messages in thread
From: Rusty Russell @ 2002-07-31 3:26 UTC (permalink / raw)
To: Kai Germaschewski; +Cc: Roman Zippel, linux-kernel
In message <Pine.LNX.4.44.0207302110570.19799-100000@chaos.physics.uiowa.edu> y
ou write:
> - It looks like with your current approach you can't have a ',' or '-' in
> KBUILD_MODNAME - however, that means that KBUILD_MODNAME is not quite
> right for passing module parameters for built-in modules on the command
> line, it would be confusing to pass parameters for ide-cd as
> ide_cd.foo=whatever. So that part could use a little more thought.
My PARAM code actually maps - to _ in parameter parsing, for exactly
this reason. And only a complete idiot would put , in a module name,
so I don't care 8)
> - It's possible that objects are linked into more than one module - I
> suppose this shouldn't be a problem, since these objects hopefully
> don't have a module_init() nor do they export symbols. Not sure if your
> patch did handle this.
There's one piece of code I know which is linked in three places, and
has a module parameter (net/ipv4/netfilter/ip_conntrack_core.c, linked
into ipfwadm.o ipchains.o and ip_conntrack.o.
As it happens, the configuration doesn't allow more than one to be
built in (they can all be modules though), so it's not actually a
problem even after parameter unification.
Thanks,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-07-31 3:26 ` Rusty Russell
@ 2002-07-31 17:06 ` Kai Germaschewski
2002-07-31 23:28 ` Rusty Russell
0 siblings, 1 reply; 36+ messages in thread
From: Kai Germaschewski @ 2002-07-31 17:06 UTC (permalink / raw)
To: Rusty Russell; +Cc: Roman Zippel, linux-kernel
On Wed, 31 Jul 2002, Rusty Russell wrote:
> My PARAM code actually maps - to _ in parameter parsing, for exactly
> this reason. And only a complete idiot would put , in a module name,
> so I don't care 8)
Tell that to the author of 53c7,8xx.o ;)
> > - It's possible that objects are linked into more than one module - I
> > suppose this shouldn't be a problem, since these objects hopefully
> > don't have a module_init() nor do they export symbols. Not sure if your
> > patch did handle this.
>
> There's one piece of code I know which is linked in three places, and
> has a module parameter (net/ipv4/netfilter/ip_conntrack_core.c, linked
> into ipfwadm.o ipchains.o and ip_conntrack.o.
>
> As it happens, the configuration doesn't allow more than one to be
> built in (they can all be modules though), so it's not actually a
> problem even after parameter unification.
Hmmh, I think that'll need some testing. It will be fine if only one of
the three is "y", the others being "n/undef". However, it looks like it's
possible to have sth like "m/m/y", which would go wrong with the current
approach.
--Kai
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-07-31 17:06 ` Kai Germaschewski
@ 2002-07-31 23:28 ` Rusty Russell
0 siblings, 0 replies; 36+ messages in thread
From: Rusty Russell @ 2002-07-31 23:28 UTC (permalink / raw)
To: Kai Germaschewski; +Cc: Roman Zippel, linux-kernel
In message <Pine.LNX.4.44.0207311201000.19799-100000@chaos.physics.uiowa.edu> y
ou write:
> On Wed, 31 Jul 2002, Rusty Russell wrote:
>
> > My PARAM code actually maps - to _ in parameter parsing, for exactly
> > this reason. And only a complete idiot would put , in a module name,
> > so I don't care 8)
>
> Tell that to the author of 53c7,8xx.o ;)
Consider that done.
> > As it happens, the configuration doesn't allow more than one to be
> > built in (they can all be modules though), so it's not actually a
> > problem even after parameter unification.
>
> Hmmh, I think that'll need some testing. It will be fine if only one of
> the three is "y", the others being "n/undef". However, it looks like it's
> possible to have sth like "m/m/y", which would go wrong with the current
> approach.
That's a bug. That configuration makes no sense (the modules won't
load). Hmmm... more Config.in complexity coming up 8(
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH] automatic module_init ordering
@ 2002-08-01 23:52 Roman Zippel
2002-08-02 3:19 ` Kai Germaschewski
0 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-08-01 23:52 UTC (permalink / raw)
To: Kai Germaschewski, linux-kernel, Rusty Russell
Hi,
This is latest version of the automatic module_init ordering patch.
IMO the patch is almost ready. A bit annoying problem is that
-DKBUILD_MODNAME=unix becomes -DKBUILD_MODNAME=1. An undef helps
of course, but I'm not sure whether we should put it on the command
line or in the source.
This patch depends on Kai's KBUILD_MODNAME patch.
Kai, do you see any possible kbuild problem left? I hope I found
everything. :)
bye, Roman
diff -Nur linux-2.5/Makefile linux-initcall/Makefile
--- linux-2.5/Makefile Fri Aug 2 00:40:57 2002
+++ linux-initcall/Makefile Thu Aug 1 23:28:32 2002
@@ -268,6 +268,7 @@
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -284,9 +285,15 @@
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+init/generated-initcalls.c: .allbuiltin_mods
+ $(CONFIG_SHELL) -e scripts/build-initcalls $< $@
+
+.allbuiltin_mods: $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)
+ for s in $(dir $^); do sed "s,^,$$s," < $${s}.builtin_mods; done > $@
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
@@ -586,6 +593,7 @@
# files removed with 'make clean'
CLEAN_FILES += \
+ init/generated-initcalls.c .allbuiltin_mods \
include/linux/compile.h \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
@@ -647,7 +655,7 @@
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .builtin_mods \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
diff -Nur linux-2.5/Rules.make linux-initcall/Rules.make
--- linux-2.5/Rules.make Fri Aug 2 00:42:14 2002
+++ linux-initcall/Rules.make Thu Aug 1 21:21:40 2002
@@ -109,7 +109,8 @@
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
+local-objs-y := $(filter-out $(subdir-obj-y), $(obj-y))
+real-objs-y := $(foreach m, $(local-objs-y), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
# Only build module versions for files which are selected to be built
@@ -268,7 +269,7 @@
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .builtin_mods
@echo -n
# Compile C sources (.c)
@@ -318,6 +319,23 @@
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+
+quiet_cmd_gen_builtin_mod = ' Generating $(echo_target)'
+define cmd_gen_builtin_mod
+ for o in $(sort $(local-objs-y)); do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
+ echo $$o; \
+ fi \
+ done > $@; \
+ for s in $(sort $(subdir-y)); do \
+ sed "s,^,$$s/," < $$s/.builtin_mods; \
+ done >> $@
+endef
+
+$(subdir-y:%=%/.builtin_mods): sub_dirs
+
+.builtin_mods: $(local-objs-y) $(subdir-y:%=%/.builtin_mods)
+ $(call if_changed,gen_builtin_mod)
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
diff -Nur linux-2.5/drivers/ide/main.c linux-initcall/drivers/ide/main.c
--- linux-2.5/drivers/ide/main.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/drivers/ide/main.c Wed Jul 31 00:51:58 2002
@@ -1397,23 +1397,6 @@
}
# endif
#endif
-
- /*
- * Initialize all device type driver modules.
- */
-#ifdef CONFIG_BLK_DEV_IDEDISK
- idedisk_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- ide_cdrom_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDEFLOPPY
- idefloppy_init();
-#endif
-
initializing = 0;
register_reboot_notifier(&ata_notifier);
diff -Nur linux-2.5/fs/dnotify.c linux-initcall/fs/dnotify.c
--- linux-2.5/fs/dnotify.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/fs/dnotify.c Wed Jul 31 00:51:58 2002
@@ -155,4 +155,4 @@
return 0;
}
-module_init(dnotify_init)
+fs_initcall(dnotify_init);
diff -Nur linux-2.5/fs/fcntl.c linux-initcall/fs/fcntl.c
--- linux-2.5/fs/fcntl.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/fs/fcntl.c Wed Jul 31 00:51:58 2002
@@ -568,4 +568,4 @@
return 0;
}
-module_init(fasync_init)
+fs_initcall(fasync_init);
diff -Nur linux-2.5/fs/locks.c linux-initcall/fs/locks.c
--- linux-2.5/fs/locks.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/fs/locks.c Wed Jul 31 00:51:58 2002
@@ -1936,4 +1936,4 @@
return 0;
}
-module_init(filelock_init)
+fs_initcall(filelock_init);
diff -Nur linux-2.5/include/linux/init.h linux-initcall/include/linux/init.h
--- linux-2.5/include/linux/init.h Fri Aug 2 00:40:57 2002
+++ linux-initcall/include/linux/init.h Wed Jul 31 00:51:58 2002
@@ -106,6 +106,9 @@
#define __FINIT .previous
#define __INITDATA .section ".data.init","aw"
+#define ___concat(a,b) a##b
+#define __concat(a,b) ___concat(a,b)
+
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -116,7 +119,10 @@
* routine with init_module() which is used by insmod and
* modprobe when the driver is used as a module.
*/
-#define module_init(x) __initcall(x);
+#define module_init(x) \
+int __attribute__((__section__ (".initcall.module"))) \
+__concat(init_module_,KBUILD_MODNAME)(void) \
+{ return x(); }
/**
* module_exit() - driver exit entry point
diff -Nur linux-2.5/kernel/module.c linux-initcall/kernel/module.c
--- linux-2.5/kernel/module.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/kernel/module.c Wed Jul 31 00:51:58 2002
@@ -252,6 +252,19 @@
arch_init_modules(&kernel_module);
}
+extern initcall_t generated_initcalls[];
+
+static int __init init_builtin_modules(void)
+{
+ initcall_t *call;
+
+ for (call = generated_initcalls; *call; call++)
+ (*call)();
+ return 0;
+}
+
+device_initcall(init_builtin_modules);
+
/*
* Copy the name of a module from user space.
*/
diff -Nur linux-2.5/net/unix/af_unix.c linux-initcall/net/unix/af_unix.c
--- linux-2.5/net/unix/af_unix.c Fri Aug 2 00:40:57 2002
+++ linux-initcall/net/unix/af_unix.c Thu Aug 1 23:31:27 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/
+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
diff -Nur linux-2.5/scripts/build-initcalls linux-initcall/scripts/build-initcalls
--- linux-2.5/scripts/build-initcalls Thu Jan 1 01:00:00 1970
+++ linux-initcall/scripts/build-initcalls Thu Aug 1 23:28:15 2002
@@ -0,0 +1,35 @@
+list=$1
+initsrc=$2
+
+# initialize files
+echo -n > .undefined.tmp
+echo -n > .defined.tmp
+
+# get all global defined/undefined symbols and sort them into the right files
+while read obj; do
+ $NM $obj | sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $(echo $obj | sed s/,/\\\\,/),p"
+done < $list |
+awk '/^U/ { print $2 " " $3 | "sort -u > .undefined.tmp" }
+ /^[TD]/ { print $2 " " $3 | "sort -u > .defined.tmp" }'
+
+# topological sort objects and append all independent objects
+join -o "1.2 2.2" .defined.tmp .undefined.tmp | sort -u | tsort > .sorted.tmp
+grep -v -f .sorted.tmp < $list > .other.tmp
+cat .other.tmp >> .sorted.tmp
+
+# extract init function call and prepare declarations and array
+while read obj; do
+ call=$($OBJDUMP -t $obj | awk '/F \.initcall\.module/ { print $6 }')
+ defs="$defs extern int $call(void);"
+ arr="$arr $call,"
+done < .sorted.tmp
+
+# finally write it
+echo "#include <linux/init.h>" > $initsrc
+echo $defs >> $initsrc
+echo 'initcall_t generated_initcalls[] = {' >> $initsrc
+echo $arr >> $initsrc
+echo '0 };' >> $initsrc
+
+# clean up
+rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-01 23:52 [PATCH] automatic module_init ordering Roman Zippel
@ 2002-08-02 3:19 ` Kai Germaschewski
2002-08-02 21:22 ` Sam Ravnborg
0 siblings, 1 reply; 36+ messages in thread
From: Kai Germaschewski @ 2002-08-02 3:19 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Rusty Russell
On Fri, 2 Aug 2002, Roman Zippel wrote:
> This is latest version of the automatic module_init ordering patch.
> IMO the patch is almost ready. A bit annoying problem is that
> -DKBUILD_MODNAME=unix becomes -DKBUILD_MODNAME=1. An undef helps
> of course, but I'm not sure whether we should put it on the command
> line or in the source.
> This patch depends on Kai's KBUILD_MODNAME patch.
> Kai, do you see any possible kbuild problem left? I hope I found
> everything. :)
> + for o in $(sort $(local-objs-y)); do \
> + if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
> + echo $$o; \
> + fi \
> + done > $@; \
> + for s in $(sort $(subdir-y)); do \
> + sed "s,^,$$s/," < $$s/.builtin_mods; \
> + done >> $@
I had to replace this with
for o in `echo $(sort $(local-objs-y))`; do \
and the like, since otherwise my shell (bash) would complain about an
empty "for o in ; do". Maybe there's a less hacky way to handle that?
BTW, it'd be also nice if scripts/build-initcalls would add some \n's to
init/generated-initcalls.c ;)
The "unix" thing is stupid. The obvious way around that is
-DKBUILD_MODNAME="unix", but unfortunately, I don't know of any
"unstringify" preprocessing function, so that doesn't work easily, either.
Well, I cannot think of a nicer solution there (and I tried ;), other than
these small issues things look very nice, though.
--Kai
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-02 3:19 ` Kai Germaschewski
@ 2002-08-02 21:22 ` Sam Ravnborg
2002-08-03 1:17 ` Kai Germaschewski
0 siblings, 1 reply; 36+ messages in thread
From: Sam Ravnborg @ 2002-08-02 21:22 UTC (permalink / raw)
To: Kai Germaschewski; +Cc: Roman Zippel, linux-kernel, Rusty Russell
On Thu, Aug 01, 2002 at 10:19:04PM -0500, Kai Germaschewski wrote:
> and the like, since otherwise my shell (bash) would complain about an
> empty "for o in ; do". Maybe there's a less hacky way to handle that?
Found what I consider less hacky way to handle it.
Test for non-empty string before executing the for loop.
Also played a little with gen_builtin_mod to make it cover all combinations
of empty and non-empty directories.
>
> BTW, it'd be also nice if scripts/build-initcalls would add some \n's to
> init/generated-initcalls.c ;)
Done.
I also made a few other changes to allow my kernel to compile.
Patch is on top of Kai's KBUILD_MODNAME and Romans latest version.
Sam
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.564 -> 1.565
# Makefile 1.284 -> 1.285
# Rules.make 1.70 -> 1.71
# scripts/build-initcalls 1.1 -> 1.2
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/02 sam@mars.ravnborg.org 1.565
# [PATCH] Automatic initcall can compile 2.5.30
# o No longer fails with minimal config
# o bash compatible
# o generated-initcalls.c readable
# --------------------------------------------
#
diff -Nru a/Makefile b/Makefile
--- a/Makefile Fri Aug 2 23:15:54 2002
+++ b/Makefile Fri Aug 2 23:15:54 2002
@@ -291,7 +291,9 @@
$(CONFIG_SHELL) -e scripts/build-initcalls $< $@
.allbuiltin_mods: $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)
- for s in $(dir $^); do sed "s,^,$$s," < $${s}.builtin_mods; done > $@
+ @$(if $^,\
+ for s in $(dir $^); do sed "s@^@$$s@" \
+ < $${s}.builtin_mods; done > $@ )
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
diff -Nru a/Rules.make b/Rules.make
--- a/Rules.make Fri Aug 2 23:15:54 2002
+++ b/Rules.make Fri Aug 2 23:15:54 2002
@@ -320,16 +320,20 @@
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
-quiet_cmd_gen_builtin_mod = ' Generating $(echo_target)'
+quiet_cmd_gen_builtin_mod = MOD $(echo_target)
define cmd_gen_builtin_mod
- for o in $(sort $(local-objs-y)); do \
- if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
- echo $$o; \
- fi \
- done > $@; \
+ (echo $(if $(local-objs-y),;) \
+ $(if $(local-objs-y), \
+ for o in $(sort $(local-objs-y)); do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
+ echo $$o; \
+ fi \
+ done) \
+ $(if $(subdir-y), ;\
for s in $(sort $(subdir-y)); do \
- sed "s,^,$$s/," < $$s/.builtin_mods; \
- done >> $@
+ sed "s@^@$$s/@" < $$s/.builtin_mods; \
+ done) \
+ ) > $@
endef
$(subdir-y:%=%/.builtin_mods): sub_dirs
diff -Nru a/scripts/build-initcalls b/scripts/build-initcalls
--- a/scripts/build-initcalls Fri Aug 2 23:15:54 2002
+++ b/scripts/build-initcalls Fri Aug 2 23:15:54 2002
@@ -7,7 +7,10 @@
# get all global defined/undefined symbols and sort them into the right files
while read obj; do
- $NM $obj | sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $(echo $obj | sed s/,/\\\\,/),p"
+ if [ -f $obj ]; then
+ $NM $obj |\
+ sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $(echo $obj | sed s/,/\\\\,/),p"
+ fi
done < $list |
awk '/^U/ { print $2 " " $3 | "sort -u > .undefined.tmp" }
/^[TD]/ { print $2 " " $3 | "sort -u > .defined.tmp" }'
@@ -19,17 +22,26 @@
# extract init function call and prepare declarations and array
while read obj; do
- call=$($OBJDUMP -t $obj | awk '/F \.initcall\.module/ { print $6 }')
- defs="$defs extern int $call(void);"
- arr="$arr $call,"
+ if [ -f $obj ]; then
+ call=$($OBJDUMP -t $obj | awk '/F \.initcall\.module/ { print $6 }')
+ defs="$defs extern int $call(void);"
+ arr="$arr $call"
+ fi
done < .sorted.tmp
# finally write it
-echo "#include <linux/init.h>" > $initsrc
-echo $defs >> $initsrc
-echo 'initcall_t generated_initcalls[] = {' >> $initsrc
-echo $arr >> $initsrc
-echo '0 };' >> $initsrc
+(
+echo "#include <linux/init.h>"
+for i in $arr; do
+ echo "extern int $i(void);"
+done
+echo
+echo 'initcall_t generated_initcalls[] = {'
+for i in $arr; do
+ echo "$i, "
+done
+echo '0 };'
+) > $initsrc
# clean up
-rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp
+#rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-02 21:22 ` Sam Ravnborg
@ 2002-08-03 1:17 ` Kai Germaschewski
2002-08-03 22:11 ` Sam Ravnborg
0 siblings, 1 reply; 36+ messages in thread
From: Kai Germaschewski @ 2002-08-03 1:17 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Roman Zippel, linux-kernel, Rusty Russell
On Fri, 2 Aug 2002, Sam Ravnborg wrote:
> On Thu, Aug 01, 2002 at 10:19:04PM -0500, Kai Germaschewski wrote:
> > and the like, since otherwise my shell (bash) would complain about an
> > empty "for o in ; do". Maybe there's a less hacky way to handle that?
> Found what I consider less hacky way to handle it.
> Test for non-empty string before executing the for loop.
Yeah. Still not exactly clean. Another suggestion I got was
+ objs="$(sort $(local-objs-y))"; for o in $$objs; do \
from Alex Riesen. This one looks the nicest to me.
> diff -Nru a/scripts/build-initcalls b/scripts/build-initcalls
> --- a/scripts/build-initcalls Fri Aug 2 23:15:54 2002
> +++ b/scripts/build-initcalls Fri Aug 2 23:15:54 2002
> @@ -7,7 +7,10 @@
>
> # get all global defined/undefined symbols and sort them into the right files
> while read obj; do
> - $NM $obj | sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $(echo $obj | sed s/,/\\\\,/),p"
> + if [ -f $obj ]; then
> + $NM $obj |\
> + sed -n "s,^[0-9a-f ]*\([UTD] .*\),\1 $(echo $obj | sed s/,/\\\\,/),p"
> + fi
> done < $list |
> awk '/^U/ { print $2 " " $3 | "sort -u > .undefined.tmp" }
> /^[TD]/ { print $2 " " $3 | "sort -u > .defined.tmp" }'
I think these should really not be necessary (didn't try, though). I would
really hope that the body won't get executed when the file is empty, and
I'd rather have it error out when one of the listed files magically
disappeared instead of silently skipping some initcalls ;)
> # finally write it
> -echo "#include <linux/init.h>" > $initsrc
> -echo $defs >> $initsrc
> -echo 'initcall_t generated_initcalls[] = {' >> $initsrc
> -echo $arr >> $initsrc
> -echo '0 };' >> $initsrc
> +(
> +echo "#include <linux/init.h>"
> +for i in $arr; do
> + echo "extern int $i(void);"
> +done
> +echo
> +echo 'initcall_t generated_initcalls[] = {'
> +for i in $arr; do
> + echo "$i, "
> +done
> +echo '0 };'
> +) > $initsrc
Looks good to me...
> # clean up
> -rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp
> +#rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp
I guess you meant to remove that part before making the patch ;)
--Kai
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-03 1:17 ` Kai Germaschewski
@ 2002-08-03 22:11 ` Sam Ravnborg
2002-08-04 15:30 ` Roman Zippel
0 siblings, 1 reply; 36+ messages in thread
From: Sam Ravnborg @ 2002-08-03 22:11 UTC (permalink / raw)
To: Kai Germaschewski; +Cc: Sam Ravnborg, Roman Zippel, linux-kernel, Rusty Russell
On Fri, Aug 02, 2002 at 08:17:17PM -0500, Kai Germaschewski wrote:
> Yeah. Still not exactly clean. Another suggestion I got was
>
> + objs="$(sort $(local-objs-y))"; for o in $$objs; do \
>
> from Alex Riesen. This one looks the nicest to me.
Looks indeed better!
But in order to avoid malfunction for the directories where there
is no initcalls you still need to fiddle with $(if $(local-objs-y)
and similar for subdir-y.
The trick is to add only the needed number of ';', no more no less.
Try playing around with:
$> make mrproper allnoconfig
$> make
Another issue that I noticed after submitting the patch was that
due to the fact the 'echo' in gen_build... always create a .builtin_mods
file, there appear a number of lines only listing an empty directory
witin .allbuiltin_mods.
I would recommend to
1) Use sed to get rid of the empty lines,
2) to do something like this in the Makefile:
init/generated-initcalls.c: $(wildcard $(addsuffix /.builtin_mods,\
$(dir $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)))
$(CONFIG_SHELL) -e scripts/build-initcalls $< $^ $@
And then move the contatenation of the .builtin_mods files to
build-initcalls.
Giving the above a second thought I do not understand the usage of
"$^" when generating .allbuiltin_mods. Don't you miss initcalls in subdirs
that are not being updated?
I would say that an all or nothing approach is more correct.
Another issue:
If I do:
$> find -name '.builtin_mods' | xargs rm -f
$> make
the .builtin_mods files are not regenerated. Some rule are missing...
Sam
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-03 22:11 ` Sam Ravnborg
@ 2002-08-04 15:30 ` Roman Zippel
2002-08-04 20:04 ` Sam Ravnborg
2002-08-05 6:13 ` Rusty Russell
0 siblings, 2 replies; 36+ messages in thread
From: Roman Zippel @ 2002-08-04 15:30 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Kai Germaschewski, linux-kernel, Rusty Russell, martin
[-- Attachment #1: Type: text/plain, Size: 1224 bytes --]
Hi,
Martin, could you please check the ide initialization? Why are device
type driver initialized twice? If I try to remove one of them, one
machine here doesn't boot anymore.
Sam Ravnborg wrote:
> Another issue that I noticed after submitting the patch was that
> due to the fact the 'echo' in gen_build... always create a .builtin_mods
> file, there appear a number of lines only listing an empty directory
> witin .allbuiltin_mods.
.builtin_mods should be empty in this case.
> 2) to do something like this in the Makefile:
> init/generated-initcalls.c: $(wildcard $(addsuffix /.builtin_mods,\
> $(dir $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS)))
> $(CONFIG_SHELL) -e scripts/build-initcalls $< $^ $@
> And then move the contatenation of the .builtin_mods files to
> build-initcalls.
Nice idea. Done.
> Another issue:
> If I do:
> $> find -name '.builtin_mods' | xargs rm -f
> $> make
> the .builtin_mods files are not regenerated. Some rule are missing...
Could you try the attached patch? It should fix all the mentioned
problems. Files are now regenerated only if something really changed.
if_changed needed a fix to correctly save the command line and
dependencies should be correct now.
bye, Roman
[-- Attachment #2: initcall.diff --]
[-- Type: text/plain, Size: 13289 bytes --]
diff -Nur -X /opt/home/roman/nodiff linux-2.5/Makefile linux-initcall/Makefile
--- linux-2.5/Makefile Sun Aug 4 02:33:23 2002
+++ linux-initcall/Makefile Sun Aug 4 15:01:11 2002
@@ -268,6 +268,7 @@
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -283,13 +284,26 @@
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+builtin_mods := $(addsuffix .builtin_mods,$(sort $(dir $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS))))
+
+quiet_cmd_gen_initcalls = GEN $@
+cmd_gen_initcalls = $(CONFIG_SHELL) -e scripts/build-initcalls $@ $(builtin_mods)
+
+define rule_gen_initcalls
+ $(call cmd,gen_initcalls)
+ @echo 'cmd_$(@F) := $(cmd_gen_initcalls)' > .$(@F).cmd
+endef
+
+init/generated-initcalls.c: $(builtin_mods) FORCE
+ $(call if_changed_rule,gen_initcalls)
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
-$(sort $(vmlinux-objs)): $(SUBDIRS) ;
+$(sort $(vmlinux-objs)) $(builtin_mods): $(SUBDIRS) ;
# Handle descending into subdirectories listed in $(SUBDIRS)
@@ -585,7 +599,7 @@
# files removed with 'make clean'
CLEAN_FILES += \
- include/linux/compile.h \
+ include/linux/compile.h init/generated-initcalls.c \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
drivers/char/conmakehash \
@@ -646,7 +660,7 @@
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .builtin_mods \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
diff -Nur -X /opt/home/roman/nodiff linux-2.5/Rules.make linux-initcall/Rules.make
--- linux-2.5/Rules.make Sun Aug 4 15:10:11 2002
+++ linux-initcall/Rules.make Sun Aug 4 02:34:52 2002
@@ -95,17 +95,22 @@
multi-used-y := $(filter-out $(list-multi),$(__multi-used-y))
multi-used-m := $(filter-out $(list-multi),$(__multi-used-m))
+multi-used := $(multi-used-y) $(multi-used-m)
+
# Build list of the parts of our composite objects, our composite
# objects depend on those (obviously)
multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)))
multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)))
+multi-objs := $(multi-objs-y) $(multi-objs-m)
+
# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
# in the local directory
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
+local-objs-y := $(filter-out $(subdir-obj-y), $(obj-y))
+real-objs-y := $(foreach m, $(local-objs-y), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
# Only build module versions for files which are selected to be built
@@ -115,6 +120,23 @@
# contain a comma
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
+# These flags are needed for modversions and compiling, so we define them here
+# already
+# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
+# end up in (or would, if it gets compiled in)
+# Note: It's possible that one object gets potentially linked into more
+# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
+# where foo and bar are the name of the modules.
+basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
+modname_flags = -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))
+c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
+ $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
+ $(basename_flags) $(modname_flags) $(export_flags)
+
+# Finds the multi-part object the current object will be linked into
+modname-multi = $(subst $(space),_,$(strip $(foreach m,$(multi-used),\
+ $(if $(filter $(*F).o,$($(m:.o=-objs))),$(m:.o=)))))
+
# We're called for one of three purposes:
# o fastdep: build module version files (.ver) for $(export-objs) in
# the current directory
@@ -164,11 +186,10 @@
$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL)
$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE)
$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__
+# Default for not multi-part modules
+modname = $(*F)
-c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
- $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
- -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
- $(export_flags)
+$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi)
# Our objects only depend on modversions.h, not on the individual .ver
# files (fix-dep filters them), so touch modversions.h if any of the .ver
@@ -248,7 +269,7 @@
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .builtin_mods
@echo -n
# Compile C sources (.c)
@@ -259,6 +280,7 @@
$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
$(export-objs) : export_flags := $(EXPORT_FLAGS)
@@ -266,10 +288,13 @@
$(export-objs:.o=.s) : export_flags := $(EXPORT_FLAGS)
$(export-objs:.o=.lst): export_flags := $(EXPORT_FLAGS)
-c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
- $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
- -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
- $(export_flags)
+# Default for not multi-part modules
+modname = $(*F)
+
+$(multi-objs) : modname = $(modname-multi)
+$(multi-objs:.o=.i) : modname = $(modname-multi)
+$(multi-objs:.o=.s) : modname = $(modname-multi)
+$(multi-objs:.o=.lst) : modname = $(modname-multi)
quiet_cmd_cc_s_c = CC $(echo_target)
cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
@@ -295,6 +320,25 @@
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+subdir-builtin_mods := $(addsuffix /.builtin_mods,$(subdir-y))
+
+$(subdir-builtin_mods): sub_dirs
+
+quiet_cmd_gen_builtin_mod = MOD $(echo_target)
+define cmd_gen_builtin_mod
+ objs="$(sort $(local-objs-y))"; for o in $$objs; do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
+ echo $$o; \
+ fi \
+ done > $@; \
+ dirs="$(sort $(subdir-y))"; for d in $$dirs; do \
+ sed "s,^,$$d/," < $$d/.builtin_mods; \
+ done >> $@
+endef
+
+.builtin_mods: $(local-objs-y) $(subdir-builtin_mods) FORCE
+ $(call if_changed,gen_builtin_mod)
+
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
@@ -318,7 +362,7 @@
%.o: %.S FORCE
$(call if_changed_dep,as_o_S)
-targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS)
+targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS) .builtin_mods
# Build the compiled-in targets
# ---------------------------------------------------------------------------
@@ -523,7 +567,7 @@
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
$(cmd_$(1)); \
- echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd)
+ echo 'cmd_$@ := $(subst $$,$$$$,$(cmd_$(1)))' > $(@D)/.$(@F).cmd)
# execute the command and also postprocess generated .d dependencies
@@ -535,7 +579,7 @@
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
$(cmd_$(1)); \
- $(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
+ $(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(subst $$,$$$$,$(cmd_$(1)))' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
diff -Nur -X /opt/home/roman/nodiff linux-2.5/drivers/ide/main.c linux-initcall/drivers/ide/main.c
--- linux-2.5/drivers/ide/main.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/drivers/ide/main.c Sun Aug 4 02:34:52 2002
@@ -1417,23 +1417,6 @@
}
# endif
#endif
-
- /*
- * Initialize all device type driver modules.
- */
-#ifdef CONFIG_BLK_DEV_IDEDISK
- idedisk_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- ide_cdrom_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDEFLOPPY
- idefloppy_init();
-#endif
-
initializing = 0;
register_reboot_notifier(&ata_notifier);
diff -Nur -X /opt/home/roman/nodiff linux-2.5/fs/dnotify.c linux-initcall/fs/dnotify.c
--- linux-2.5/fs/dnotify.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/fs/dnotify.c Sun Aug 4 02:34:52 2002
@@ -155,4 +155,4 @@
return 0;
}
-module_init(dnotify_init)
+fs_initcall(dnotify_init);
diff -Nur -X /opt/home/roman/nodiff linux-2.5/fs/fcntl.c linux-initcall/fs/fcntl.c
--- linux-2.5/fs/fcntl.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/fs/fcntl.c Sun Aug 4 02:34:52 2002
@@ -568,4 +568,4 @@
return 0;
}
-module_init(fasync_init)
+fs_initcall(fasync_init);
diff -Nur -X /opt/home/roman/nodiff linux-2.5/fs/locks.c linux-initcall/fs/locks.c
--- linux-2.5/fs/locks.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/fs/locks.c Sun Aug 4 02:34:52 2002
@@ -1890,4 +1890,4 @@
return 0;
}
-module_init(filelock_init)
+fs_initcall(filelock_init);
diff -Nur -X /opt/home/roman/nodiff linux-2.5/include/linux/init.h linux-initcall/include/linux/init.h
--- linux-2.5/include/linux/init.h Sun Aug 4 02:33:23 2002
+++ linux-initcall/include/linux/init.h Sun Aug 4 02:34:52 2002
@@ -106,6 +106,9 @@
#define __FINIT .previous
#define __INITDATA .section ".data.init","aw"
+#define ___concat(a,b) a##b
+#define __concat(a,b) ___concat(a,b)
+
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -116,7 +119,10 @@
* routine with init_module() which is used by insmod and
* modprobe when the driver is used as a module.
*/
-#define module_init(x) __initcall(x);
+#define module_init(x) \
+int __attribute__((__section__ (".initcall.module"))) \
+__concat(init_module_,KBUILD_MODNAME)(void) \
+{ return x(); }
/**
* module_exit() - driver exit entry point
diff -Nur -X /opt/home/roman/nodiff linux-2.5/kernel/module.c linux-initcall/kernel/module.c
--- linux-2.5/kernel/module.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/kernel/module.c Sun Aug 4 02:34:52 2002
@@ -252,6 +252,19 @@
arch_init_modules(&kernel_module);
}
+extern initcall_t generated_initcalls[];
+
+static int __init init_builtin_modules(void)
+{
+ initcall_t *call;
+
+ for (call = generated_initcalls; *call; call++)
+ (*call)();
+ return 0;
+}
+
+device_initcall(init_builtin_modules);
+
/*
* Copy the name of a module from user space.
*/
diff -Nur -X /opt/home/roman/nodiff linux-2.5/net/unix/af_unix.c linux-initcall/net/unix/af_unix.c
--- linux-2.5/net/unix/af_unix.c Sun Aug 4 02:33:23 2002
+++ linux-initcall/net/unix/af_unix.c Sun Aug 4 02:34:52 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/
+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
diff -Nur -X /opt/home/roman/nodiff linux-2.5/scripts/build-initcalls linux-initcall/scripts/build-initcalls
--- linux-2.5/scripts/build-initcalls Thu Jan 1 01:00:00 1970
+++ linux-initcall/scripts/build-initcalls Sun Aug 4 15:00:04 2002
@@ -0,0 +1,45 @@
+initsrc=$1
+shift
+
+# initialize files
+echo -n > .undefined.tmp
+echo -n > .defined.tmp
+echo -n > .all.tmp
+
+# get all global defined/undefined symbols and sort them into the right files
+for file in $@; do
+ sed "s;^;$(dirname $file)/;" < $file |
+ while read obj; do
+ echo $obj >> .all.tmp
+ $NM $obj | sed -n "s;^[0-9a-f ]*\([UTD] .*\);\1 $obj;p"
+ done
+done |
+awk '/^U/ { print $2 " " $3 | "sort -u > .undefined.tmp" }
+ /^[TD]/ { print $2 " " $3 | "sort -u > .defined.tmp" }'
+
+# topological sort objects and append all independent objects
+join -o "1.2 2.2" .defined.tmp .undefined.tmp | sort -u | tsort > .sorted.tmp
+grep -v -f .sorted.tmp < .all.tmp > .other.tmp
+cat .other.tmp >> .sorted.tmp
+
+# extract init function call and prepare declarations and array
+while read obj; do
+ call=$($OBJDUMP -t $obj | awk '/F \.initcall\.module/ { print $6 }')
+ arr="$arr $call"
+done < .sorted.tmp
+
+# finally write it
+(
+ echo "#include <linux/init.h>"
+ for f in $arr; do
+ echo "extern int $f(void);"
+ done
+ echo "initcall_t __initdata generated_initcalls[] = {"
+ for f in $arr; do
+ echo " $f,"
+ done
+ echo "0 };"
+) > $initsrc
+
+# clean up
+rm .undefined.tmp .defined.tmp .all.tmp .sorted.tmp .other.tmp
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-04 15:30 ` Roman Zippel
@ 2002-08-04 20:04 ` Sam Ravnborg
2002-08-04 20:10 ` Sam Ravnborg
2002-08-05 6:13 ` Rusty Russell
1 sibling, 1 reply; 36+ messages in thread
From: Sam Ravnborg @ 2002-08-04 20:04 UTC (permalink / raw)
To: Roman Zippel
Cc: Sam Ravnborg, Kai Germaschewski, linux-kernel, Rusty Russell,
martin
On Sun, Aug 04, 2002 at 05:30:47PM +0200, Roman Zippel wrote:
>
> Could you try the attached patch? It should fix all the mentioned
> problems. Files are now regenerated only if something really changed.
> if_changed needed a fix to correctly save the command line and
> dependencies should be correct now.
Looks good, a few comments remains. We are down to matter of personal taste.
> +builtin_mods := $(addsuffix .builtin_mods,$(sort $(dir $(CORE_FILES) $(LIBS)
$(DRIVERS) $(NETWORKS))))
A verbose comment above this line descibing the whole concept about initcalls
would be nice. Keep it short and informative.
> + @echo 'cmd_$(@F) := $(cmd_gen_initcalls)' > .$(@F).cmd
I would like to see $(notdir and the counterpart $(dir used instead of
$(@F) and $(@D). The latter two are deprecated by make.
See make.info.
This is general for all of kbuild, but since this is new stuff I bring it up.
Sam
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-04 20:04 ` Sam Ravnborg
@ 2002-08-04 20:10 ` Sam Ravnborg
0 siblings, 0 replies; 36+ messages in thread
From: Sam Ravnborg @ 2002-08-04 20:10 UTC (permalink / raw)
To: Roman Zippel, Sam Ravnborg, Kai Germaschewski, linux-kernel,
Rusty Russell, martin
On Sun, Aug 04, 2002 at 10:04:17PM +0200, Sam Ravnborg wrote:
> Looks good, a few comments remains. We are down to matter of personal taste.
One more, let this be the last one...
Doing:
$> make KBUILD_VERBOSE=0
..... Compilation succeeds
$> make KBUILD_VERBOSE=0
make[1]: `generated-initcalls.o' is up to date.
make[2]: `vmlinux' is up to date.
Could we please get rid of the superflous 'generated-initcalls.o' is up ....
Sam
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-04 15:30 ` Roman Zippel
2002-08-04 20:04 ` Sam Ravnborg
@ 2002-08-05 6:13 ` Rusty Russell
2002-08-05 19:05 ` Roman Zippel
1 sibling, 1 reply; 36+ messages in thread
From: Rusty Russell @ 2002-08-05 6:13 UTC (permalink / raw)
To: Roman Zippel; +Cc: Kai Germaschewski, linux-kernel
In message <3D4D48A7.6BA919D2@linux-m68k.org> you write:
> Hi,
>
> Martin, could you please check the ide initialization? Why are device
> type driver initialized twice? If I try to remove one of them, one
> machine here doesn't boot anymore.
Sorry for being out of the loop for a while.
This patch takes Roman's work and massages it a little so the addition
of explicit initcall dependencies is easier. I'm testing it now (see
my kernel.org page for updates).
1) Rename build-initcalls to build-module-initcalls
2) Generate explicit calls, which is clearer than an array.
3) Simplify (and hopefully speed up) by calling $(NM) once for all files.
4) Call initcalls from init/main.c rather then kernel/module.c
There seems to be a problem in that .allbuiltin_mods doesn't include
stuff in net/ipv4/netfilter/.builtin_mods for example (set
CONFIG_NETFILTER=y, CONFIG_IP_NF_IPTABLES=y, everything else there to Y).
Rusty.
PS. Patch requires Kai's -DMODNAME patch, also on kernel.org page.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Module initcall depends
Author: Roman Zippel
Status: Experimental
Depends: Misc/kbuild_object.patch.gz
D: The initialization of modules which are built into the kernel can be
D: derived implicitly from their dependencies. This patch does that,
D: and also makes module_init() illegal for code which can never be a module.
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/Makefile working-2.5.30-module-init/Makefile
--- working-2.5.30-modname/Makefile 2002-08-02 11:15:05.000000000 +1000
+++ working-2.5.30-module-init/Makefile 2002-08-05 15:33:49.000000000 +1000
@@ -268,6 +268,7 @@ cmd_link_vmlinux = $(LD) $(LDFLAGS) $(LD
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -283,9 +284,22 @@ define rule_link_vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+builtin_mods := $(addsuffix .builtin_mods,$(sort $(dir $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS))))
+
+quiet_cmd_gen_initcalls = GEN $@
+cmd_gen_initcalls = $(CONFIG_SHELL) scripts/build-initcalls $(builtin_mods) > $@
+
+define rule_gen_initcalls
+ $(call cmd,gen_initcalls)
+ @echo 'cmd_$(@F) := $(cmd_gen_initcalls)' > .$(@F).cmd
+endef
+
+init/generated-initcalls.c: $(builtin_mods) FORCE
+ $(call if_changed_rule,gen_initcalls)
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
@@ -585,6 +599,7 @@ defconfig:
# files removed with 'make clean'
CLEAN_FILES += \
+ .allbuiltin_mods \
include/linux/compile.h \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
@@ -646,7 +661,7 @@ clean: archclean
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .builtin_mods -o -name generated\* -o -name .generated\* \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/Rules.make working-2.5.30-module-init/Rules.make
--- working-2.5.30-modname/Rules.make 2002-08-05 15:50:27.000000000 +1000
+++ working-2.5.30-module-init/Rules.make 2002-08-05 15:28:23.000000000 +1000
@@ -268,7 +269,7 @@ endif
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .builtin_mods
@echo -n
# Compile C sources (.c)
@@ -319,6 +320,25 @@ cmd_cc_lst_c = $(CC) $(c_flags) -g -
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+subdir-builtin_mods := $(addsuffix /.builtin_mods,$(subdir-y))
+
+$(subdir-builtin_mods): sub_dirs
+
+quiet_cmd_gen_builtin_mod = MOD $(echo_target)
+define cmd_gen_builtin_mod
+ objs="$(sort $(local-objs-y))"; for o in $$objs; do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
+ echo $$o; \
+ fi \
+ done > $@; \
+ dirs="$(sort $(subdir-y))"; for d in $$dirs; do \
+ sed "s,^,$$d/," < $$d/.builtin_mods; \
+ done >> $@
+endef
+
+.builtin_mods: $(local-objs-y) $(subdir-builtin_mods) FORCE
+ $(call if_changed,gen_builtin_mod)
+
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/drivers/ide/main.c working-2.5.30-module-init/drivers/ide/main.c
--- working-2.5.30-modname/drivers/ide/main.c 2002-08-02 11:15:08.000000000 +1000
+++ working-2.5.30-module-init/drivers/ide/main.c 2002-08-05 15:19:31.000000000 +1000
@@ -1417,23 +1417,6 @@ static int __init ata_module_init(void)
}
# endif
#endif
-
- /*
- * Initialize all device type driver modules.
- */
-#ifdef CONFIG_BLK_DEV_IDEDISK
- idedisk_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- ide_cdrom_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_init();
-#endif
-#ifdef CONFIG_BLK_DEV_IDEFLOPPY
- idefloppy_init();
-#endif
-
initializing = 0;
register_reboot_notifier(&ata_notifier);
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/include/linux/init.h working-2.5.30-module-init/include/linux/init.h
--- working-2.5.30-modname/include/linux/init.h 2002-06-10 16:03:55.000000000 +1000
+++ working-2.5.30-module-init/include/linux/init.h 2002-08-05 15:19:31.000000000 +1000
@@ -106,6 +111,9 @@ extern struct kernel_param __setup_start
#define __FINIT .previous
#define __INITDATA .section ".data.init","aw"
+#define ___concat(a,b) a##b
+#define __concat(a,b) ___concat(a,b)
+
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -116,7 +124,10 @@ extern struct kernel_param __setup_start
* routine with init_module() which is used by insmod and
* modprobe when the driver is used as a module.
*/
-#define module_init(x) __initcall(x);
+#define module_init(x) \
+int __attribute__((__section__ (".initcall.module"))) \
+__concat(init_module_,KBUILD_MODNAME)(void) \
+{ return x(); }
/**
* module_exit() - driver exit entry point
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/init/main.c working-2.5.30-module-init/init/main.c
--- working-2.5.30-modname/init/main.c 2002-08-02 11:15:10.000000000 +1000
+++ working-2.5.30-module-init/init/main.c 2002-08-05 15:21:32.000000000 +1000
@@ -464,6 +464,8 @@ asmlinkage void __init start_kernel(void
struct task_struct *child_reaper = &init_task;
+extern void do_module_initcalls(void);
+
static void __init do_initcalls(void)
{
initcall_t *call;
@@ -474,6 +476,8 @@ static void __init do_initcalls(void)
call++;
} while (call < &__initcall_end);
+ do_module_initcalls();
+
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_tasks();
}
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/net/irda/irsyms.c working-2.5.30-module-init/net/irda/irsyms.c
--- working-2.5.30-modname/net/irda/irsyms.c 2002-06-21 09:41:57.000000000 +1000
+++ working-2.5.30-module-init/net/irda/irsyms.c 2002-08-05 15:19:31.000000000 +1000
@@ -332,7 +332,7 @@ void __exit irda_cleanup(void)
*
* Jean II
*/
-subsys_initcall(irda_init);
+module_init(irda_init);
module_exit(irda_cleanup);
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> & Jean Tourrilhes <jt@hpl.hp.com>");
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/net/unix/af_unix.c working-2.5.30-module-init/net/unix/af_unix.c
--- working-2.5.30-modname/net/unix/af_unix.c 2002-07-17 10:25:54.000000000 +1000
+++ working-2.5.30-module-init/net/unix/af_unix.c 2002-08-05 15:19:31.000000000 +1000
@@ -79,6 +79,8 @@
* with BSD names.
*/
+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
diff -urpN -I '\$.*\$' --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-2.5.30-modname/scripts/build-module-initcalls working-2.5.30-module-init/scripts/build-module-initcalls
--- working-2.5.30-modname/scripts/build-module-initcalls 1970-01-01 10:00:00.000000000 +1000
+++ working-2.5.30-module-init/scripts/build-module-initcalls 2002-08-05 15:33:22.000000000 +1000
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Given a list of module objects, spit out C code to call all the inits
+# in order, based on dependencies.
+
+# Don't do this in the top line, as we are invoked with sh explicitly.
+set -e
+
+# Clean up however we exit.
+trap 'rm .undefined.tmp .defined.tmp .sorted.tmp .other.tmp' 0
+
+# initialize files
+echo -n > .undefined.tmp
+echo -n > .defined.tmp
+
+# get all global defined/undefined symbols and sort them into the right files
+for f; do sed "s;^;$(dirname $f)/;" < $f; done | xargs $NM -A |
+ awk '/:[ ]*U/ { sub(/:[ ]*U/," "); print $0 | "sort -u > .undefined.tmp" }
+ /:[A-Fa-f0-9 ]*[TD]/ { sub(/:[A-Fa-f0-9 ]*[TD]/," "); print $0 | "sort -u > .defined.tmp" }'
+
+# topological sort objects and append all independent objects
+join -1 2 -2 2 -o "1.1 2.1" .defined.tmp .undefined.tmp | sort -u | tsort > .sorted.tmp
+fgrep -v -f .sorted.tmp < $list > .other.tmp
+cat .other.tmp >> .sorted.tmp
+
+# Output header.
+echo '/* Builtin module initcalls: autogenerated by build-module-initcalls */'
+echo '#include <linux/init.h>'
+echo ''
+echo 'void __init do_module_initcalls(void)'
+echo '{'
+
+$OBJDUMP -t `cat .sorted.tmp .other.tmp` |
+ awk '/F \.initcall\.module/ { print " { extern int " $6 "(void); " $6 "(); }" }'
+echo '}'
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-05 6:13 ` Rusty Russell
@ 2002-08-05 19:05 ` Roman Zippel
2002-08-06 7:28 ` Rusty Russell
0 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-08-05 19:05 UTC (permalink / raw)
To: Rusty Russell; +Cc: Kai Germaschewski, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]
Hi,
Rusty Russell wrote:
> 1) Rename build-initcalls to build-module-initcalls
> 2) Generate explicit calls, which is clearer than an array.
> 3) Simplify (and hopefully speed up) by calling $(NM) once for all files.
> 4) Call initcalls from init/main.c rather then kernel/module.c
>
> There seems to be a problem in that .allbuiltin_mods doesn't include
> stuff in net/ipv4/netfilter/.builtin_mods for example (set
> CONFIG_NETFILTER=y, CONFIG_IP_NF_IPTABLES=y, everything else there to Y).
Are you sure sent the right patch? This one misses a few changes.
Anyway, I stole all the good ideas and integrated them into my patch. :)
- I use a separate initcall for the module initialization, that's the
only way I can solve my IDE problems.
- I put the initcall for that directly into the generated file.
- raid autodetect became a late_initcall()
- I don't use trap to clean up, so people can send us the temporary
files, if something should go wrong. These files will be removed by a
normal 'make clean' anyway.
bye, Roman
[-- Attachment #2: modinit.diff --]
[-- Type: text/plain, Size: 19208 bytes --]
diff -Nur linux-modname/Makefile linux-modinit/Makefile
--- linux-modname/Makefile Sun Aug 4 02:33:23 2002
+++ linux-modinit/Makefile Mon Aug 5 20:30:36 2002
@@ -268,6 +268,7 @@
$(DRIVERS) \
$(NETWORKS) \
--end-group \
+ init/generated-initcalls.o \
-o vmlinux
# set -e makes the rule exit immediately on error
@@ -283,13 +284,29 @@
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
-vmlinux: $(vmlinux-objs) FORCE
+vmlinux: $(vmlinux-objs) init/generated-initcalls.o FORCE
$(call if_changed_rule,link_vmlinux)
+# .builtin_mods contains a list of objects with module_init() calls
+# sort these calls into the right order similiar to depmod
+
+builtin_mods := $(addsuffix .builtin_mods,$(sort $(dir $(CORE_FILES) $(LIBS) $(DRIVERS) $(NETWORKS))))
+
+quiet_cmd_gen_initcalls = GEN $@
+cmd_gen_initcalls = $(CONFIG_SHELL) scripts/build-module-initcalls > $@ $(builtin_mods)
+
+define rule_gen_initcalls
+ $(call cmd,gen_initcalls)
+ @echo 'cmd_$(notdir $@) := $(cmd_gen_initcalls)' > .$(notdir $@).cmd
+endef
+
+init/generated-initcalls.c: $(builtin_mods) scripts/build-module-initcalls FORCE
+ $(call if_changed_rule,gen_initcalls)
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
-$(sort $(vmlinux-objs)): $(SUBDIRS) ;
+$(sort $(vmlinux-objs)) $(builtin_mods): $(SUBDIRS) ;
# Handle descending into subdirectories listed in $(SUBDIRS)
@@ -585,7 +602,7 @@
# files removed with 'make clean'
CLEAN_FILES += \
- include/linux/compile.h \
+ include/linux/compile.h init/generated-initcalls.c \
vmlinux System.map \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
drivers/char/conmakehash \
@@ -646,7 +663,7 @@
@echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
- -name .\*.tmp -o -name .\*.d \) -type f -print \
+ -name .\*.tmp -o -name .\*.d -o -name .builtin_mods \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
@rm -f $(CLEAN_FILES)
@$(MAKE) -f Documentation/DocBook/Makefile clean
diff -Nur linux-modname/Rules.make linux-modinit/Rules.make
--- linux-modname/Rules.make Mon Aug 5 19:54:16 2002
+++ linux-modinit/Rules.make Mon Aug 5 19:55:47 2002
@@ -109,7 +109,8 @@
subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
+local-objs-y := $(filter-out $(subdir-obj-y), $(obj-y))
+real-objs-y := $(foreach m, $(local-objs-y), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $($(m:.o=-objs)),$($(m:.o=-objs)),$(m)))
# Only build module versions for files which are selected to be built
@@ -268,7 +269,7 @@
# The echo suppresses the "Nothing to be done for first_rule"
first_rule: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
- sub_dirs
+ sub_dirs .builtin_mods
@echo -n
# Compile C sources (.c)
@@ -319,6 +320,25 @@
%.lst: %.c FORCE
$(call if_changed_dep,cc_lst_c)
+subdir-builtin_mods := $(addsuffix /.builtin_mods,$(subdir-y))
+
+$(subdir-builtin_mods): sub_dirs
+
+quiet_cmd_gen_builtin_mod = MOD $(echo_target)
+define cmd_gen_builtin_mod
+ objs="$(sort $(local-objs-y))"; for o in $$objs; do \
+ if [ -n "$$($(OBJDUMP) -h $$o | grep .initcall.module)" ]; then \
+ echo $$o; \
+ fi \
+ done > $@; \
+ dirs="$(sort $(subdir-y))"; for d in $$dirs; do \
+ sed "s,^,$$d/," < $$d/.builtin_mods; \
+ done >> $@
+endef
+
+.builtin_mods: $(local-objs-y) $(subdir-builtin_mods) FORCE
+ $(call if_changed,gen_builtin_mod)
+
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
@@ -342,7 +362,7 @@
%.o: %.S FORCE
$(call if_changed_dep,as_o_S)
-targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS)
+targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS) .builtin_mods
# Build the compiled-in targets
# ---------------------------------------------------------------------------
@@ -547,7 +567,7 @@
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
$(cmd_$(1)); \
- echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd)
+ echo 'cmd_$@ := $(subst $$,$$$$,$(cmd_$(1)))' > $(@D)/.$(@F).cmd)
# execute the command and also postprocess generated .d dependencies
@@ -559,7 +579,7 @@
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
$(cmd_$(1)); \
- $(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
+ $(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(subst $$,$$$$,$(cmd_$(1)))' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
diff -Nur linux-modname/arch/alpha/vmlinux.lds.in linux-modinit/arch/alpha/vmlinux.lds.in
--- linux-modname/arch/alpha/vmlinux.lds.in Sun Aug 4 15:10:23 2002
+++ linux-modinit/arch/alpha/vmlinux.lds.in Mon Aug 5 19:55:47 2002
@@ -55,6 +55,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
__initcall_end = .;
}
diff -Nur linux-modname/arch/arm/vmlinux-armo.lds.in linux-modinit/arch/arm/vmlinux-armo.lds.in
--- linux-modname/arch/arm/vmlinux-armo.lds.in Sun Aug 4 15:10:25 2002
+++ linux-modinit/arch/arm/vmlinux-armo.lds.in Mon Aug 5 19:55:47 2002
@@ -34,6 +34,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
__initcall_end = .;
. = ALIGN(32768);
__init_end = .;
diff -Nur linux-modname/arch/arm/vmlinux-armv.lds.in linux-modinit/arch/arm/vmlinux-armv.lds.in
--- linux-modname/arch/arm/vmlinux-armv.lds.in Sun Aug 4 15:10:25 2002
+++ linux-modinit/arch/arm/vmlinux-armv.lds.in Mon Aug 5 19:55:47 2002
@@ -34,6 +34,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
__initcall_end = .;
. = ALIGN(4096);
__init_end = .;
diff -Nur linux-modname/arch/cris/cris.ld linux-modinit/arch/cris/cris.ld
--- linux-modname/arch/cris/cris.ld Sun Aug 4 15:10:36 2002
+++ linux-modinit/arch/cris/cris.ld Mon Aug 5 19:55:47 2002
@@ -70,6 +70,7 @@
*(.initcall5.init);
*(.initcall6.init);
*(.initcall7.init);
+ *(.initcall8.init);
__initcall_end = .;
/* We fill to the next page, so we can discard all init
diff -Nur linux-modname/arch/i386/vmlinux.lds linux-modinit/arch/i386/vmlinux.lds
--- linux-modname/arch/i386/vmlinux.lds Sun Aug 4 15:10:37 2002
+++ linux-modinit/arch/i386/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -56,6 +56,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/arch/ia64/vmlinux.lds.S linux-modinit/arch/ia64/vmlinux.lds.S
--- linux-modname/arch/ia64/vmlinux.lds.S Sun Aug 4 15:10:39 2002
+++ linux-modinit/arch/ia64/vmlinux.lds.S Mon Aug 5 19:55:47 2002
@@ -108,6 +108,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(PAGE_SIZE);
diff -Nur linux-modname/arch/m68k/vmlinux-sun3.lds linux-modinit/arch/m68k/vmlinux-sun3.lds
--- linux-modname/arch/m68k/vmlinux-sun3.lds Sun Aug 4 15:10:45 2002
+++ linux-modinit/arch/m68k/vmlinux-sun3.lds Mon Aug 5 19:55:47 2002
@@ -51,6 +51,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(8192);
diff -Nur linux-modname/arch/m68k/vmlinux.lds linux-modinit/arch/m68k/vmlinux.lds
--- linux-modname/arch/m68k/vmlinux.lds Sun Aug 4 15:10:45 2002
+++ linux-modinit/arch/m68k/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -55,6 +55,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(8192);
diff -Nur linux-modname/arch/mips/ld.script.in linux-modinit/arch/mips/ld.script.in
--- linux-modname/arch/mips/ld.script.in Sun Aug 4 15:10:51 2002
+++ linux-modinit/arch/mips/ld.script.in Mon Aug 5 19:55:47 2002
@@ -52,6 +52,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(4096); /* Align double page for init_task_union */
diff -Nur linux-modname/arch/mips64/ld.script.elf32.S linux-modinit/arch/mips64/ld.script.elf32.S
--- linux-modname/arch/mips64/ld.script.elf32.S Sun Aug 4 15:10:59 2002
+++ linux-modinit/arch/mips64/ld.script.elf32.S Mon Aug 5 19:55:47 2002
@@ -48,6 +48,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(4096); /* Align double page for init_task_union */
diff -Nur linux-modname/arch/mips64/ld.script.elf64 linux-modinit/arch/mips64/ld.script.elf64
--- linux-modname/arch/mips64/ld.script.elf64 Sun Aug 4 15:10:59 2002
+++ linux-modinit/arch/mips64/ld.script.elf64 Mon Aug 5 19:55:47 2002
@@ -58,6 +58,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(4096); /* Align double page for init_task_union */
diff -Nur linux-modname/arch/parisc/vmlinux.lds linux-modinit/arch/parisc/vmlinux.lds
--- linux-modname/arch/parisc/vmlinux.lds Sun Aug 4 15:11:01 2002
+++ linux-modinit/arch/parisc/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -60,6 +60,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
__init_end = .;
diff -Nur linux-modname/arch/ppc/vmlinux.lds linux-modinit/arch/ppc/vmlinux.lds
--- linux-modname/arch/ppc/vmlinux.lds Sun Aug 4 15:11:01 2002
+++ linux-modinit/arch/ppc/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -110,6 +110,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/arch/ppc64/vmlinux.lds linux-modinit/arch/ppc64/vmlinux.lds
--- linux-modname/arch/ppc64/vmlinux.lds Sun Aug 4 15:11:07 2002
+++ linux-modinit/arch/ppc64/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -108,6 +108,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/arch/s390/vmlinux-shared.lds linux-modinit/arch/s390/vmlinux-shared.lds
--- linux-modname/arch/s390/vmlinux-shared.lds Sun Aug 4 15:11:11 2002
+++ linux-modinit/arch/s390/vmlinux-shared.lds Mon Aug 5 19:55:47 2002
@@ -60,6 +60,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(256);
diff -Nur linux-modname/arch/s390/vmlinux.lds linux-modinit/arch/s390/vmlinux.lds
--- linux-modname/arch/s390/vmlinux.lds Sun Aug 4 15:11:11 2002
+++ linux-modinit/arch/s390/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -56,6 +56,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(256);
diff -Nur linux-modname/arch/s390x/vmlinux-shared.lds linux-modinit/arch/s390x/vmlinux-shared.lds
--- linux-modname/arch/s390x/vmlinux-shared.lds Sun Aug 4 15:11:12 2002
+++ linux-modinit/arch/s390x/vmlinux-shared.lds Mon Aug 5 19:55:47 2002
@@ -60,6 +60,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(256);
diff -Nur linux-modname/arch/s390x/vmlinux.lds linux-modinit/arch/s390x/vmlinux.lds
--- linux-modname/arch/s390x/vmlinux.lds Sun Aug 4 15:11:12 2002
+++ linux-modinit/arch/s390x/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -56,6 +56,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(256);
diff -Nur linux-modname/arch/sh/vmlinux.lds.S linux-modinit/arch/sh/vmlinux.lds.S
--- linux-modname/arch/sh/vmlinux.lds.S Sun Aug 4 15:11:12 2002
+++ linux-modinit/arch/sh/vmlinux.lds.S Mon Aug 5 19:55:47 2002
@@ -72,6 +72,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
__machvec_start = .;
diff -Nur linux-modname/arch/sparc/vmlinux.lds linux-modinit/arch/sparc/vmlinux.lds
--- linux-modname/arch/sparc/vmlinux.lds Sun Aug 4 15:11:17 2002
+++ linux-modinit/arch/sparc/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -54,6 +54,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/arch/sparc64/vmlinux.lds linux-modinit/arch/sparc64/vmlinux.lds
--- linux-modname/arch/sparc64/vmlinux.lds Sun Aug 4 15:11:19 2002
+++ linux-modinit/arch/sparc64/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -55,6 +55,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/arch/x86_64/vmlinux.lds linux-modinit/arch/x86_64/vmlinux.lds
--- linux-modname/arch/x86_64/vmlinux.lds Sun Aug 4 15:11:21 2002
+++ linux-modinit/arch/x86_64/vmlinux.lds Mon Aug 5 19:55:47 2002
@@ -96,6 +96,7 @@
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
+ *(.initcall8.init)
}
__initcall_end = .;
. = ALIGN(32);
diff -Nur linux-modname/drivers/md/md.c linux-modinit/drivers/md/md.c
--- linux-modname/drivers/md/md.c Sun Aug 4 15:11:53 2002
+++ linux-modinit/drivers/md/md.c Mon Aug 5 19:55:47 2002
@@ -3237,6 +3237,29 @@
return (0);
}
+void __exit md_exit(void)
+{
+ md_unregister_thread(md_recovery_thread);
+ devfs_unregister(devfs_handle);
+
+ unregister_blkdev(MAJOR_NR,"md");
+ unregister_reboot_notifier(&md_notifier);
+ unregister_sysctl_table(raid_table_header);
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("mdstat", NULL);
+#endif
+
+ del_gendisk(&md_gendisk);
+ blk_dev[MAJOR_NR].queue = NULL;
+ blk_clear(MAJOR_NR);
+
+ while (!list_empty(&device_names)) {
+ dev_name_t *tmp = list_entry(device_names.next,
+ dev_name_t, list);
+ list_del(&tmp->list);
+ kfree(tmp);
+ }
+}
#ifndef MODULE
@@ -3539,46 +3562,12 @@
__setup("raid=", raid_setup);
__setup("md=", md_setup);
-__initcall(md_init);
-__initcall(md_run_setup);
-
-#else /* It is a MODULE */
-
-int init_module(void)
-{
- return md_init();
-}
-
-static void free_device_names(void)
-{
- while (!list_empty(&device_names)) {
- dev_name_t *tmp = list_entry(device_names.next,
- dev_name_t, list);
- list_del(&tmp->list);
- kfree(tmp);
- }
-}
+late_initcall(md_run_setup);
-
-void cleanup_module(void)
-{
- md_unregister_thread(md_recovery_thread);
- devfs_unregister(devfs_handle);
-
- unregister_blkdev(MAJOR_NR,"md");
- unregister_reboot_notifier(&md_notifier);
- unregister_sysctl_table(raid_table_header);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("mdstat", NULL);
#endif
- del_gendisk(&md_gendisk);
- blk_dev[MAJOR_NR].queue = NULL;
- blk_clear(MAJOR_NR);
-
- free_device_names();
-}
-#endif
+module_init(md_init);
+module_exit(md_exit);
EXPORT_SYMBOL(md_size);
EXPORT_SYMBOL(register_md_personality);
diff -Nur linux-modname/fs/dnotify.c linux-modinit/fs/dnotify.c
--- linux-modname/fs/dnotify.c Sun Aug 4 02:33:23 2002
+++ linux-modinit/fs/dnotify.c Mon Aug 5 19:55:47 2002
@@ -155,4 +155,4 @@
return 0;
}
-module_init(dnotify_init)
+fs_initcall(dnotify_init);
diff -Nur linux-modname/fs/fcntl.c linux-modinit/fs/fcntl.c
--- linux-modname/fs/fcntl.c Sun Aug 4 02:33:23 2002
+++ linux-modinit/fs/fcntl.c Mon Aug 5 19:55:47 2002
@@ -568,4 +568,4 @@
return 0;
}
-module_init(fasync_init)
+fs_initcall(fasync_init);
diff -Nur linux-modname/fs/locks.c linux-modinit/fs/locks.c
--- linux-modname/fs/locks.c Sun Aug 4 02:33:23 2002
+++ linux-modinit/fs/locks.c Mon Aug 5 19:55:47 2002
@@ -1890,4 +1890,4 @@
return 0;
}
-module_init(filelock_init)
+fs_initcall(filelock_init);
diff -Nur linux-modname/include/linux/init.h linux-modinit/include/linux/init.h
--- linux-modname/include/linux/init.h Sun Aug 4 02:33:23 2002
+++ linux-modinit/include/linux/init.h Mon Aug 5 19:55:47 2002
@@ -66,7 +66,8 @@
#define subsys_initcall(fn) __define_initcall("4",fn)
#define fs_initcall(fn) __define_initcall("5",fn)
#define device_initcall(fn) __define_initcall("6",fn)
-#define late_initcall(fn) __define_initcall("7",fn)
+#define module_initcall(fn) __define_initcall("7",fn)
+#define late_initcall(fn) __define_initcall("8",fn)
#define __initcall(fn) device_initcall(fn)
@@ -106,6 +107,9 @@
#define __FINIT .previous
#define __INITDATA .section ".data.init","aw"
+#define ___concat(a,b) a##b
+#define __concat(a,b) ___concat(a,b)
+
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -116,7 +120,10 @@
* routine with init_module() which is used by insmod and
* modprobe when the driver is used as a module.
*/
-#define module_init(x) __initcall(x);
+#define module_init(x) \
+int __attribute__((__section__ (".initcall.module"))) \
+__concat(init_module_,KBUILD_MODNAME)(void) \
+{ return x(); }
/**
* module_exit() - driver exit entry point
diff -Nur linux-modname/net/unix/af_unix.c linux-modinit/net/unix/af_unix.c
--- linux-modname/net/unix/af_unix.c Sun Aug 4 02:33:23 2002
+++ linux-modinit/net/unix/af_unix.c Mon Aug 5 19:55:47 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/
+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
diff -Nur linux-modname/scripts/build-module-initcalls linux-modinit/scripts/build-module-initcalls
--- linux-modname/scripts/build-module-initcalls Thu Jan 1 01:00:00 1970
+++ linux-modinit/scripts/build-module-initcalls Mon Aug 5 19:55:47 2002
@@ -0,0 +1,37 @@
+#! /bin/sh
+# Given a list of module objects, spit out C code to call all the inits
+# in order, based on dependencies.
+
+set -e
+
+# initialize files
+echo -n > .undefined.tmp
+echo -n > .defined.tmp
+
+# get all global defined/undefined symbols and sort them into the right files
+for file in $@; do
+ sed "s;^;$(dirname $file)/;" < $file
+done > .all.tmp
+xargs $NM -A < .all.tmp |
+awk -F "[ : ]*" \
+ '$2 == "U" { print $3 " " $1 | "sort -u > .undefined.tmp" }
+ $3 ~ /[TD]/ { print $4 " " $1 | "sort -u > .defined.tmp" }'
+
+# topological sort objects and append all independent objects
+join -o "1.2 2.2" .defined.tmp .undefined.tmp | sort -u | tsort > .sorted.tmp
+grep -v -f .sorted.tmp < .all.tmp > .other.tmp || true
+
+# extract init function calls and write them
+echo "/* Builtin module initcalls: autogenerated by $0 */"
+echo "#include <linux/init.h>"
+echo "static int __init init_builtin_modules(void)"
+echo "{"
+cat .sorted.tmp .other.tmp |
+xargs $OBJDUMP -t |
+awk '/F \.initcall\.module/ { print " { extern int " $6 "(void);\n " $6 "(); }" }'
+echo " return 0;"
+echo "}"
+echo "module_initcall(init_builtin_modules);"
+
+# clean up
+rm .undefined.tmp .defined.tmp .all.tmp .sorted.tmp .other.tmp
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-05 19:05 ` Roman Zippel
@ 2002-08-06 7:28 ` Rusty Russell
2002-08-06 18:57 ` Roman Zippel
0 siblings, 1 reply; 36+ messages in thread
From: Rusty Russell @ 2002-08-06 7:28 UTC (permalink / raw)
To: Roman Zippel; +Cc: Kai Germaschewski, linux-kernel
In message <3D4ECC69.F0084A2C@linux-m68k.org> you write:
> Are you sure sent the right patch? This one misses a few changes.
> Anyway, I stole all the good ideas and integrated them into my patch. :)
Great, I was hoping you'd do that!
> - I use a separate initcall for the module initialization, that's the
> only way I can solve my IDE problems.
That's horrible 8( I think we need figure out why this is happening:
do you know? What does it actually need?
Ahh, I just came across the same problem! See my
ordered-core-initcalls patch, for bio.c changes: you probably need to
change this too (and I deleted the redundany explicit IDE inits).
> - I put the initcall for that directly into the generated file.
> - raid autodetect became a late_initcall()
Icky, but that's what my follow-on patch for explicit initcalls is
for. So raid is an example where it doesn't have an implicit
dependency, but it does have an actual dependency.
> - I don't use trap to clean up, so people can send us the temporary
> files, if something should go wrong. These files will be removed by a
> normal 'make clean' anyway.
Hmmm... Good idea, at least for the moment. Eventually we won't have
any bugs 8)
I've updated my explicit core initcalls patch on top of your new one,
thanks!
http://www.kernel.org/pub/linux/kernel/people/rusty/Misc/ordered-core-initcalls.patch.2.5.30.gz
It reverts your module initcall change, and boots here.
Cheers!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-06 7:28 ` Rusty Russell
@ 2002-08-06 18:57 ` Roman Zippel
2002-08-07 1:05 ` Rusty Russell
0 siblings, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-08-06 18:57 UTC (permalink / raw)
To: Rusty Russell; +Cc: Kai Germaschewski, linux-kernel
Hi,
On Tue, 6 Aug 2002, Rusty Russell wrote:
> > - I use a separate initcall for the module initialization, that's the
> > only way I can solve my IDE problems.
>
> That's horrible 8( I think we need figure out why this is happening:
> do you know? What does it actually need?
I think pci initialization.
> I've updated my explicit core initcalls patch on top of your new one,
> thanks!
>
> http://www.kernel.org/pub/linux/kernel/people/rusty/Misc/ordered-core-initcalls.patch.2.5.30.gz
I'm not sure we should go this way. My main problem is that it only solves
a single ordering problem - boot time ordering. What about suspend/wakeup?
We have more of these ordering problems and driverfs is supposed to help
with them, so I'd rather first would like to see how much we can fix this
way.
bye, Roman
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-06 18:57 ` Roman Zippel
@ 2002-08-07 1:05 ` Rusty Russell
2002-08-07 2:28 ` Kai Germaschewski
2002-08-07 10:40 ` Roman Zippel
0 siblings, 2 replies; 36+ messages in thread
From: Rusty Russell @ 2002-08-07 1:05 UTC (permalink / raw)
To: Roman Zippel; +Cc: Kai Germaschewski, linux-kernel
In message <Pine.LNX.4.44.0208062031040.28515-100000@serv> you write:
> Hi,
>
> On Tue, 6 Aug 2002, Rusty Russell wrote:
>
> > > - I use a separate initcall for the module initialization, that's the
> > > only way I can solve my IDE problems.
> >
> > That's horrible 8( I think we need figure out why this is happening:
> > do you know? What does it actually need?
>
> I think pci initialization.
>
> > I've updated my explicit core initcalls patch on top of your new one,
> > thanks!
> >
> > http://www.kernel.org/pub/linux/kernel/people/rusty/Misc/ordered-core-i
nitcalls.patch.2.5.30.gz
>
> I'm not sure we should go this way. My main problem is that it only solves
> a single ordering problem - boot time ordering. What about suspend/wakeup?
> We have more of these ordering problems and driverfs is supposed to help
> with them, so I'd rather first would like to see how much we can fix this
> way.
suspend/wakeup is a device issue, solved well by devicefs. This is
completely independent from the subtleties of initialization order in
the core kernel code: devices are not the problem.
Look at how many places have explicit initializers with #ifdef
CONFIG_XXX around them, because initialization order problems were too
hard before. These can now be fixed as desired.
I really want *one* place where you can see what order things are
initalized. If that means one big file with #ifdef's, fine. But the
current approach of using link order, initializer levels and explicit
initializers is really hard to debug and modify.
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-07 1:05 ` Rusty Russell
@ 2002-08-07 2:28 ` Kai Germaschewski
2002-08-07 10:40 ` Roman Zippel
1 sibling, 0 replies; 36+ messages in thread
From: Kai Germaschewski @ 2002-08-07 2:28 UTC (permalink / raw)
To: Rusty Russell; +Cc: Roman Zippel, linux-kernel
On Wed, 7 Aug 2002, Rusty Russell wrote:
> > I'm not sure we should go this way. My main problem is that it only solves
> > a single ordering problem - boot time ordering. What about suspend/wakeup?
> > We have more of these ordering problems and driverfs is supposed to help
> > with them, so I'd rather first would like to see how much we can fix this
> > way.
>
> suspend/wakeup is a device issue, solved well by devicefs. This is
> completely independent from the subtleties of initialization order in
> the core kernel code: devices are not the problem.
>
> Look at how many places have explicit initializers with #ifdef
> CONFIG_XXX around them, because initialization order problems were too
> hard before. These can now be fixed as desired.
>
> I really want *one* place where you can see what order things are
> initalized. If that means one big file with #ifdef's, fine. But the
> current approach of using link order, initializer levels and explicit
> initializers is really hard to debug and modify.
Since I'm still CC'ed, I thought I could add in my 2 cents, too ;)
I agree with Rusty, his ordered initcalls are really needed most at early
points during the system initialization, way before device discovery and
initialization. They allow for a lot of cleanup and clarification in that
area, so I definitely think they should go in.
Those initcalls that only do pci_register_driver() and the like are
typically the module_init() functions and are taken care of by Roman's
patch. Also, inserting devices into the device tree and handling them can
only happen after the kernel knows about the drivers, which it only does
after the corresponding initcall has run. The place where to insert them
is however an entirely different story, and that's handled by the device
tree just fine.
--Kai
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-07 1:05 ` Rusty Russell
2002-08-07 2:28 ` Kai Germaschewski
@ 2002-08-07 10:40 ` Roman Zippel
2002-08-07 11:10 ` Rusty Russell
1 sibling, 1 reply; 36+ messages in thread
From: Roman Zippel @ 2002-08-07 10:40 UTC (permalink / raw)
To: Rusty Russell; +Cc: Kai Germaschewski, linux-kernel
Hi,
On Wed, 7 Aug 2002, Rusty Russell wrote:
> > I'm not sure we should go this way. My main problem is that it only solves
> > a single ordering problem - boot time ordering. What about suspend/wakeup?
> > We have more of these ordering problems and driverfs is supposed to help
> > with them, so I'd rather first would like to see how much we can fix this
> > way.
>
> suspend/wakeup is a device issue, solved well by devicefs. This is
> completely independent from the subtleties of initialization order in
> the core kernel code: devices are not the problem.
If you see the pci code as a bus device driver, it becomes a problem. I
looked at the remaining initcalls in my kernel and most of them are for
pci. I think pci is rather abusing the initcall system.
I have that idea that pci (like other buses) could become a "normal"
driver module (one will probably never compile it as a module, but one
could at least manage it like one).
So if we integrate the bus initalizations into the device initializations,
there isn't much left of the current initcalls.
> Look at how many places have explicit initializers with #ifdef
> CONFIG_XXX around them, because initialization order problems were too
> hard before. These can now be fixed as desired.
>
> I really want *one* place where you can see what order things are
> initalized. If that means one big file with #ifdef's, fine. But the
> current approach of using link order, initializer levels and explicit
> initializers is really hard to debug and modify.
I agree that it's currently a mess, maybe your solution is the better in
the short term to make the dependencies explicit, I'm not sure about that.
My idea is to handle as much as possible over the module/driver
initialization mechanisms and leave initcalls as special cases.
bye, Roman
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] automatic module_init ordering
2002-08-07 10:40 ` Roman Zippel
@ 2002-08-07 11:10 ` Rusty Russell
0 siblings, 0 replies; 36+ messages in thread
From: Rusty Russell @ 2002-08-07 11:10 UTC (permalink / raw)
To: Roman Zippel; +Cc: Kai Germaschewski, linux-kernel
In message <Pine.LNX.4.44.0208071208210.28515-100000@serv> you write:
> Hi,
>
> On Wed, 7 Aug 2002, Rusty Russell wrote:
>
> > suspend/wakeup is a device issue, solved well by devicefs. This is
> > completely independent from the subtleties of initialization order in
> > the core kernel code: devices are not the problem.
>
> If you see the pci code as a bus device driver, it becomes a problem. I
> looked at the remaining initcalls in my kernel and most of them are for
> pci. I think pci is rather abusing the initcall system.
> I have that idea that pci (like other buses) could become a "normal"
> driver module (one will probably never compile it as a module, but one
> could at least manage it like one).
> So if we integrate the bus initalizations into the device initializations,
> there isn't much left of the current initcalls.
Yes, that's a very astute observation about PCI. But we will still
have the hard ones left, like the initcalls which want to be called
before SMP, or two-sided registration mechanisms (anything which has
registration of servers and clients) still requires ordering.
> > I really want *one* place where you can see what order things are
> > initalized. If that means one big file with #ifdef's, fine. But the
> > current approach of using link order, initializer levels and explicit
> > initializers is really hard to debug and modify.
>
> I agree that it's currently a mess, maybe your solution is the better in
> the short term to make the dependencies explicit, I'm not sure about that.
> My idea is to handle as much as possible over the module/driver
> initialization mechanisms and leave initcalls as special cases.
The best thing about the explicit initcalls is that they document
everything they are relying on, so they can be replaced. At the
moment it's very hard to see how to replace an initcall (does it rely
on link order for example).
I don't think we can complete the conversion before 2.6, so I think we
need both. If explicit core initcalls become v. rare, great!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2002-08-07 11:15 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-27 20:22 [PATCH] automatic initcalls Roman Zippel
2002-07-28 3:31 ` Rusty Russell
2002-07-28 3:51 ` Jeff Garzik
2002-07-28 4:47 ` Linus Torvalds
2002-07-28 8:50 ` Keith Adamson
2002-07-28 18:59 ` Oliver Xymoron
2002-07-29 23:39 ` Rusty Russell
2002-07-29 8:39 ` Ingo Oeser
2002-07-30 2:49 ` Keith Adamson
2002-07-30 2:51 ` Keith Adamson
2002-07-28 12:18 ` Roman Zippel
2002-07-29 23:46 ` Rusty Russell
2002-07-30 23:04 ` [PATCH] automatic module_init ordering Roman Zippel
2002-07-31 2:33 ` Kai Germaschewski
2002-07-31 3:26 ` Rusty Russell
2002-07-31 17:06 ` Kai Germaschewski
2002-07-31 23:28 ` Rusty Russell
2002-07-28 21:59 ` [PATCH] automatic initcalls Kai Germaschewski
2002-07-29 18:56 ` Patrick Mochel
2002-07-29 20:14 ` Roman Zippel
-- strict thread matches above, loose matches on Subject: below --
2002-08-01 23:52 [PATCH] automatic module_init ordering Roman Zippel
2002-08-02 3:19 ` Kai Germaschewski
2002-08-02 21:22 ` Sam Ravnborg
2002-08-03 1:17 ` Kai Germaschewski
2002-08-03 22:11 ` Sam Ravnborg
2002-08-04 15:30 ` Roman Zippel
2002-08-04 20:04 ` Sam Ravnborg
2002-08-04 20:10 ` Sam Ravnborg
2002-08-05 6:13 ` Rusty Russell
2002-08-05 19:05 ` Roman Zippel
2002-08-06 7:28 ` Rusty Russell
2002-08-06 18:57 ` Roman Zippel
2002-08-07 1:05 ` Rusty Russell
2002-08-07 2:28 ` Kai Germaschewski
2002-08-07 10:40 ` Roman Zippel
2002-08-07 11:10 ` Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox