diff options
Diffstat (limited to 'init/main.c')
-rw-r--r-- | init/main.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/init/main.c b/init/main.c index 5c8540271529..4ab5124a2952 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -62,14 +62,13 @@ | |||
62 | #include <linux/sched.h> | 62 | #include <linux/sched.h> |
63 | #include <linux/signal.h> | 63 | #include <linux/signal.h> |
64 | #include <linux/idr.h> | 64 | #include <linux/idr.h> |
65 | #include <linux/kgdb.h> | ||
65 | #include <linux/ftrace.h> | 66 | #include <linux/ftrace.h> |
66 | #include <linux/async.h> | 67 | #include <linux/async.h> |
67 | #include <linux/kmemcheck.h> | 68 | #include <linux/kmemcheck.h> |
68 | #include <linux/kmemtrace.h> | ||
69 | #include <linux/sfi.h> | 69 | #include <linux/sfi.h> |
70 | #include <linux/shmem_fs.h> | 70 | #include <linux/shmem_fs.h> |
71 | #include <linux/slab.h> | 71 | #include <linux/slab.h> |
72 | #include <trace/boot.h> | ||
73 | 72 | ||
74 | #include <asm/io.h> | 73 | #include <asm/io.h> |
75 | #include <asm/bugs.h> | 74 | #include <asm/bugs.h> |
@@ -124,7 +123,9 @@ static char *ramdisk_execute_command; | |||
124 | 123 | ||
125 | #ifdef CONFIG_SMP | 124 | #ifdef CONFIG_SMP |
126 | /* Setup configured maximum number of CPUs to activate */ | 125 | /* Setup configured maximum number of CPUs to activate */ |
127 | unsigned int __initdata setup_max_cpus = NR_CPUS; | 126 | unsigned int setup_max_cpus = NR_CPUS; |
127 | EXPORT_SYMBOL(setup_max_cpus); | ||
128 | |||
128 | 129 | ||
129 | /* | 130 | /* |
130 | * Setup routine for controlling SMP activation | 131 | * Setup routine for controlling SMP activation |
@@ -421,18 +422,26 @@ static void __init setup_command_line(char *command_line) | |||
421 | * gcc-3.4 accidentally inlines this function, so use noinline. | 422 | * gcc-3.4 accidentally inlines this function, so use noinline. |
422 | */ | 423 | */ |
423 | 424 | ||
425 | static __initdata DECLARE_COMPLETION(kthreadd_done); | ||
426 | |||
424 | static noinline void __init_refok rest_init(void) | 427 | static noinline void __init_refok rest_init(void) |
425 | __releases(kernel_lock) | 428 | __releases(kernel_lock) |
426 | { | 429 | { |
427 | int pid; | 430 | int pid; |
428 | 431 | ||
429 | rcu_scheduler_starting(); | 432 | rcu_scheduler_starting(); |
433 | /* | ||
434 | * We need to spawn init first so that it obtains pid 1, however | ||
435 | * the init task will end up wanting to create kthreads, which, if | ||
436 | * we schedule it before we create kthreadd, will OOPS. | ||
437 | */ | ||
430 | kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); | 438 | kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); |
431 | numa_default_policy(); | 439 | numa_default_policy(); |
432 | pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); | 440 | pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); |
433 | rcu_read_lock(); | 441 | rcu_read_lock(); |
434 | kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); | 442 | kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); |
435 | rcu_read_unlock(); | 443 | rcu_read_unlock(); |
444 | complete(&kthreadd_done); | ||
436 | unlock_kernel(); | 445 | unlock_kernel(); |
437 | 446 | ||
438 | /* | 447 | /* |
@@ -566,7 +575,7 @@ asmlinkage void __init start_kernel(void) | |||
566 | setup_per_cpu_areas(); | 575 | setup_per_cpu_areas(); |
567 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ | 576 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ |
568 | 577 | ||
569 | build_all_zonelists(); | 578 | build_all_zonelists(NULL); |
570 | page_alloc_init(); | 579 | page_alloc_init(); |
571 | 580 | ||
572 | printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); | 581 | printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); |
@@ -652,7 +661,6 @@ asmlinkage void __init start_kernel(void) | |||
652 | #endif | 661 | #endif |
653 | page_cgroup_init(); | 662 | page_cgroup_init(); |
654 | enable_debug_pagealloc(); | 663 | enable_debug_pagealloc(); |
655 | kmemtrace_init(); | ||
656 | kmemleak_init(); | 664 | kmemleak_init(); |
657 | debug_objects_mem_init(); | 665 | debug_objects_mem_init(); |
658 | idr_init_cache(); | 666 | idr_init_cache(); |
@@ -675,6 +683,7 @@ asmlinkage void __init start_kernel(void) | |||
675 | buffer_init(); | 683 | buffer_init(); |
676 | key_init(); | 684 | key_init(); |
677 | security_init(); | 685 | security_init(); |
686 | dbg_late_init(); | ||
678 | vfs_caches_init(totalram_pages); | 687 | vfs_caches_init(totalram_pages); |
679 | signals_init(); | 688 | signals_init(); |
680 | /* rootfs populating might need page-writeback */ | 689 | /* rootfs populating might need page-writeback */ |
@@ -713,38 +722,33 @@ int initcall_debug; | |||
713 | core_param(initcall_debug, initcall_debug, bool, 0644); | 722 | core_param(initcall_debug, initcall_debug, bool, 0644); |
714 | 723 | ||
715 | static char msgbuf[64]; | 724 | static char msgbuf[64]; |
716 | static struct boot_trace_call call; | ||
717 | static struct boot_trace_ret ret; | ||
718 | 725 | ||
719 | int do_one_initcall(initcall_t fn) | 726 | int do_one_initcall(initcall_t fn) |
720 | { | 727 | { |
721 | int count = preempt_count(); | 728 | int count = preempt_count(); |
722 | ktime_t calltime, delta, rettime; | 729 | ktime_t calltime, delta, rettime; |
730 | unsigned long long duration; | ||
731 | int ret; | ||
723 | 732 | ||
724 | if (initcall_debug) { | 733 | if (initcall_debug) { |
725 | call.caller = task_pid_nr(current); | 734 | printk("calling %pF @ %i\n", fn, task_pid_nr(current)); |
726 | printk("calling %pF @ %i\n", fn, call.caller); | ||
727 | calltime = ktime_get(); | 735 | calltime = ktime_get(); |
728 | trace_boot_call(&call, fn); | ||
729 | enable_boot_trace(); | ||
730 | } | 736 | } |
731 | 737 | ||
732 | ret.result = fn(); | 738 | ret = fn(); |
733 | 739 | ||
734 | if (initcall_debug) { | 740 | if (initcall_debug) { |
735 | disable_boot_trace(); | ||
736 | rettime = ktime_get(); | 741 | rettime = ktime_get(); |
737 | delta = ktime_sub(rettime, calltime); | 742 | delta = ktime_sub(rettime, calltime); |
738 | ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10; | 743 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
739 | trace_boot_ret(&ret, fn); | 744 | printk("initcall %pF returned %d after %lld usecs\n", fn, |
740 | printk("initcall %pF returned %d after %Ld usecs\n", fn, | 745 | ret, duration); |
741 | ret.result, ret.duration); | ||
742 | } | 746 | } |
743 | 747 | ||
744 | msgbuf[0] = 0; | 748 | msgbuf[0] = 0; |
745 | 749 | ||
746 | if (ret.result && ret.result != -ENODEV && initcall_debug) | 750 | if (ret && ret != -ENODEV && initcall_debug) |
747 | sprintf(msgbuf, "error code %d ", ret.result); | 751 | sprintf(msgbuf, "error code %d ", ret); |
748 | 752 | ||
749 | if (preempt_count() != count) { | 753 | if (preempt_count() != count) { |
750 | strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf)); | 754 | strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf)); |
@@ -758,7 +762,7 @@ int do_one_initcall(initcall_t fn) | |||
758 | printk("initcall %pF returned with %s\n", fn, msgbuf); | 762 | printk("initcall %pF returned with %s\n", fn, msgbuf); |
759 | } | 763 | } |
760 | 764 | ||
761 | return ret.result; | 765 | return ret; |
762 | } | 766 | } |
763 | 767 | ||
764 | 768 | ||
@@ -853,6 +857,10 @@ static noinline int init_post(void) | |||
853 | 857 | ||
854 | static int __init kernel_init(void * unused) | 858 | static int __init kernel_init(void * unused) |
855 | { | 859 | { |
860 | /* | ||
861 | * Wait until kthreadd is all set-up. | ||
862 | */ | ||
863 | wait_for_completion(&kthreadd_done); | ||
856 | lock_kernel(); | 864 | lock_kernel(); |
857 | 865 | ||
858 | /* | 866 | /* |
@@ -878,7 +886,6 @@ static int __init kernel_init(void * unused) | |||
878 | smp_prepare_cpus(setup_max_cpus); | 886 | smp_prepare_cpus(setup_max_cpus); |
879 | 887 | ||
880 | do_pre_smp_initcalls(); | 888 | do_pre_smp_initcalls(); |
881 | start_boot_trace(); | ||
882 | 889 | ||
883 | smp_init(); | 890 | smp_init(); |
884 | sched_init_smp(); | 891 | sched_init_smp(); |