diff options
Diffstat (limited to 'init/main.c')
-rw-r--r-- | init/main.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/init/main.c b/init/main.c index ac2e4a5f59ee..4ddb53f04f2a 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -424,18 +424,26 @@ static void __init setup_command_line(char *command_line) | |||
424 | * gcc-3.4 accidentally inlines this function, so use noinline. | 424 | * gcc-3.4 accidentally inlines this function, so use noinline. |
425 | */ | 425 | */ |
426 | 426 | ||
427 | static __initdata DECLARE_COMPLETION(kthreadd_done); | ||
428 | |||
427 | static noinline void __init_refok rest_init(void) | 429 | static noinline void __init_refok rest_init(void) |
428 | __releases(kernel_lock) | 430 | __releases(kernel_lock) |
429 | { | 431 | { |
430 | int pid; | 432 | int pid; |
431 | 433 | ||
432 | rcu_scheduler_starting(); | 434 | rcu_scheduler_starting(); |
435 | /* | ||
436 | * We need to spawn init first so that it obtains pid 1, however | ||
437 | * the init task will end up wanting to create kthreads, which, if | ||
438 | * we schedule it before we create kthreadd, will OOPS. | ||
439 | */ | ||
433 | kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); | 440 | kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); |
434 | numa_default_policy(); | 441 | numa_default_policy(); |
435 | pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); | 442 | pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); |
436 | rcu_read_lock(); | 443 | rcu_read_lock(); |
437 | kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); | 444 | kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); |
438 | rcu_read_unlock(); | 445 | rcu_read_unlock(); |
446 | complete(&kthreadd_done); | ||
439 | unlock_kernel(); | 447 | unlock_kernel(); |
440 | 448 | ||
441 | /* | 449 | /* |
@@ -524,6 +532,7 @@ static void __init mm_init(void) | |||
524 | page_cgroup_init_flatmem(); | 532 | page_cgroup_init_flatmem(); |
525 | mem_init(); | 533 | mem_init(); |
526 | kmem_cache_init(); | 534 | kmem_cache_init(); |
535 | percpu_init_late(); | ||
527 | pgtable_cache_init(); | 536 | pgtable_cache_init(); |
528 | vmalloc_init(); | 537 | vmalloc_init(); |
529 | } | 538 | } |
@@ -857,6 +866,10 @@ static noinline int init_post(void) | |||
857 | 866 | ||
858 | static int __init kernel_init(void * unused) | 867 | static int __init kernel_init(void * unused) |
859 | { | 868 | { |
869 | /* | ||
870 | * Wait until kthreadd is all set-up. | ||
871 | */ | ||
872 | wait_for_completion(&kthreadd_done); | ||
860 | lock_kernel(); | 873 | lock_kernel(); |
861 | 874 | ||
862 | /* | 875 | /* |