lkml.org 
[lkml]   [2002]   [Aug]   [5]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
FromRusty Russell <>
SubjectRe: [PATCH] automatic module_init ordering
DateMon, 05 Aug 2002 16:13:36 +1000
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 '}'
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 12:27    [from the cache]
©2003-2008