aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-generic/vmlinux.lds.h2
-rw-r--r--include/linux/init.h7
-rw-r--r--init/main.c13
3 files changed, 20 insertions, 2 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 729f6b0a60e9..9cd44b162ba1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -359,6 +359,8 @@
359 } 359 }
360 360
361#define INITCALLS \ 361#define INITCALLS \
362 *(.initcallearly.init) \
363 __early_initcall_end = .; \
362 *(.initcall0.init) \ 364 *(.initcall0.init) \
363 *(.initcall0s.init) \ 365 *(.initcall0s.init) \
364 *(.initcall1.init) \ 366 *(.initcall1.init) \
diff --git a/include/linux/init.h b/include/linux/init.h
index 42ae95411a93..11b84e106053 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -170,6 +170,13 @@ extern void (*late_time_init)(void);
170 __attribute__((__section__(".initcall" level ".init"))) = fn 170 __attribute__((__section__(".initcall" level ".init"))) = fn
171 171
172/* 172/*
173 * Early initcalls run before initializing SMP.
174 *
175 * Only for built-in code, not modules.
176 */
177#define early_initcall(fn) __define_initcall("early",fn,early)
178
179/*
173 * A "pure" initcall has no dependencies on anything else, and purely 180 * A "pure" initcall has no dependencies on anything else, and purely
174 * initializes variables that couldn't be statically initialized. 181 * initializes variables that couldn't be statically initialized.
175 * 182 *
diff --git a/init/main.c b/init/main.c
index 0604cbcaf1e4..b6fec08dbbef 100644
--- a/init/main.c
+++ b/init/main.c
@@ -743,13 +743,13 @@ static void __init do_one_initcall(initcall_t fn)
743} 743}
744 744
745 745
746extern initcall_t __initcall_start[], __initcall_end[]; 746extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
747 747
748static void __init do_initcalls(void) 748static void __init do_initcalls(void)
749{ 749{
750 initcall_t *call; 750 initcall_t *call;
751 751
752 for (call = __initcall_start; call < __initcall_end; call++) 752 for (call = __early_initcall_end; call < __initcall_end; call++)
753 do_one_initcall(*call); 753 do_one_initcall(*call);
754 754
755 /* Make sure there is no pending stuff from the initcall sequence */ 755 /* Make sure there is no pending stuff from the initcall sequence */
@@ -783,6 +783,14 @@ static int __init nosoftlockup_setup(char *str)
783} 783}
784__setup("nosoftlockup", nosoftlockup_setup); 784__setup("nosoftlockup", nosoftlockup_setup);
785 785
786static void __init __do_pre_smp_initcalls(void)
787{
788 initcall_t *call;
789
790 for (call = __initcall_start; call < __early_initcall_end; call++)
791 do_one_initcall(*call);
792}
793
786static void __init do_pre_smp_initcalls(void) 794static void __init do_pre_smp_initcalls(void)
787{ 795{
788 extern int spawn_ksoftirqd(void); 796 extern int spawn_ksoftirqd(void);
@@ -865,6 +873,7 @@ static int __init kernel_init(void * unused)
865 873
866 smp_prepare_cpus(setup_max_cpus); 874 smp_prepare_cpus(setup_max_cpus);
867 875
876 __do_pre_smp_initcalls();
868 do_pre_smp_initcalls(); 877 do_pre_smp_initcalls();
869 878
870 smp_init(); 879 smp_init();