aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-07-30 15:49:02 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-08-12 03:52:54 -0400
commit59f9415ffb9759e950d775f4c400f747b332cc02 (patch)
tree354544b8cad8ae77a5f960fe601b2a3613a2523a
parent4bceba417a795b78a5146e3f85291cb7bb2402ef (diff)
modules: extend initcall_debug functionality to the module loader
The kernel has this really nice facility where if you put "initcall_debug" on the kernel commandline, it'll print which function it's going to execute just before calling an initcall, and then after the call completes it will 1) print if it had an error code 2) checks for a few simple bugs (like leaving irqs off) and 3) print how long the init call took in milliseconds. While trying to optimize the boot speed of my laptop, I have been loving number 3 to figure out what to optimize... ... and then I wished that the same thing was done for module loading. This patch makes the module loader use this exact same functionality; it's a logical extension in my view (since modules are just sort of late binding initcalls anyway) and so far I've found it quite useful in finding where things are too slow in my boot. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--include/linux/init.h1
-rw-r--r--init/main.c6
-rw-r--r--kernel/module.c2
3 files changed, 6 insertions, 3 deletions
diff --git a/include/linux/init.h b/include/linux/init.h
index 11b84e106053..93538b696e3d 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -139,6 +139,7 @@ extern initcall_t __con_initcall_start[], __con_initcall_end[];
139extern initcall_t __security_initcall_start[], __security_initcall_end[]; 139extern initcall_t __security_initcall_start[], __security_initcall_end[];
140 140
141/* Defined in init/main.c */ 141/* Defined in init/main.c */
142extern int do_one_initcall(initcall_t fn);
142extern char __initdata boot_command_line[]; 143extern char __initdata boot_command_line[];
143extern char *saved_command_line; 144extern char *saved_command_line;
144extern unsigned int reset_devices; 145extern unsigned int reset_devices;
diff --git a/init/main.c b/init/main.c
index 0bc7e167bf45..f6f7042331dc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -691,7 +691,7 @@ asmlinkage void __init start_kernel(void)
691 rest_init(); 691 rest_init();
692} 692}
693 693
694static int __initdata initcall_debug; 694static int initcall_debug;
695 695
696static int __init initcall_debug_setup(char *str) 696static int __init initcall_debug_setup(char *str)
697{ 697{
@@ -700,7 +700,7 @@ static int __init initcall_debug_setup(char *str)
700} 700}
701__setup("initcall_debug", initcall_debug_setup); 701__setup("initcall_debug", initcall_debug_setup);
702 702
703static void __init do_one_initcall(initcall_t fn) 703int do_one_initcall(initcall_t fn)
704{ 704{
705 int count = preempt_count(); 705 int count = preempt_count();
706 ktime_t t0, t1, delta; 706 ktime_t t0, t1, delta;
@@ -740,6 +740,8 @@ static void __init do_one_initcall(initcall_t fn)
740 print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn); 740 print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn);
741 printk(" returned with %s\n", msgbuf); 741 printk(" returned with %s\n", msgbuf);
742 } 742 }
743
744 return result;
743} 745}
744 746
745 747
diff --git a/kernel/module.c b/kernel/module.c
index 61d212120df4..08864d257eb0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2288,7 +2288,7 @@ sys_init_module(void __user *umod,
2288 2288
2289 /* Start the module */ 2289 /* Start the module */
2290 if (mod->init != NULL) 2290 if (mod->init != NULL)
2291 ret = mod->init(); 2291 ret = do_one_initcall(mod->init);
2292 if (ret < 0) { 2292 if (ret < 0) {
2293 /* Init routine failed: abort. Try to protect us from 2293 /* Init routine failed: abort. Try to protect us from
2294 buggy refcounters. */ 2294 buggy refcounters. */