diff options
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 2 | ||||
-rw-r--r-- | include/linux/init.h | 7 | ||||
-rw-r--r-- | init/main.c | 13 |
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 | ||
746 | extern initcall_t __initcall_start[], __initcall_end[]; | 746 | extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; |
747 | 747 | ||
748 | static void __init do_initcalls(void) | 748 | static 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 | ||
786 | static 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 | |||
786 | static void __init do_pre_smp_initcalls(void) | 794 | static 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(); |