public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] automatic module_init ordering
@ 2002-08-01 23:52 Roman Zippel
  2002-08-02  3:19 ` Kai Germaschewski
  0 siblings, 1 reply; 21+ 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] 21+ messages in thread
* Re: [PATCH] automatic initcalls
@ 2002-07-29 23:46 Rusty Russell
  2002-07-30 23:04 ` [PATCH] automatic module_init ordering Roman Zippel
  0 siblings, 1 reply; 21+ 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] 21+ messages in thread

end of thread, other threads:[~2002-08-07 11:15 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
  -- strict thread matches above, loose matches on Subject: below --
2002-07-29 23:46 [PATCH] automatic initcalls 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox