Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[sfrench/cifs-2.6.git] / init / main.c
index 5f2ec2cdd90087807086b5e82cc62e190ff462bb..e97fadeec856e4a3c1144a14513e2feb0fb99d6b 100644 (file)
 #include <linux/ftrace.h>
 #include <linux/async.h>
 #include <linux/kmemcheck.h>
-#include <linux/kmemtrace.h>
 #include <linux/sfi.h>
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
-#include <trace/boot.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -124,7 +122,9 @@ static char *ramdisk_execute_command;
 
 #ifdef CONFIG_SMP
 /* Setup configured maximum number of CPUs to activate */
-unsigned int __initdata setup_max_cpus = NR_CPUS;
+unsigned int setup_max_cpus = NR_CPUS;
+EXPORT_SYMBOL(setup_max_cpus);
+
 
 /*
  * Setup routine for controlling SMP activation
@@ -421,18 +421,26 @@ static void __init setup_command_line(char *command_line)
  * gcc-3.4 accidentally inlines this function, so use noinline.
  */
 
+static __initdata DECLARE_COMPLETION(kthreadd_done);
+
 static noinline void __init_refok rest_init(void)
        __releases(kernel_lock)
 {
        int pid;
 
        rcu_scheduler_starting();
+       /*
+        * We need to spawn init first so that it obtains pid 1, however
+        * the init task will end up wanting to create kthreads, which, if
+        * we schedule it before we create kthreadd, will OOPS.
+        */
        kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
        numa_default_policy();
        pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
        rcu_read_lock();
        kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
        rcu_read_unlock();
+       complete(&kthreadd_done);
        unlock_kernel();
 
        /*
@@ -521,6 +529,7 @@ static void __init mm_init(void)
        page_cgroup_init_flatmem();
        mem_init();
        kmem_cache_init();
+       percpu_init_late();
        pgtable_cache_init();
        vmalloc_init();
 }
@@ -652,7 +661,6 @@ asmlinkage void __init start_kernel(void)
 #endif
        page_cgroup_init();
        enable_debug_pagealloc();
-       kmemtrace_init();
        kmemleak_init();
        debug_objects_mem_init();
        idr_init_cache();
@@ -714,38 +722,33 @@ int initcall_debug;
 core_param(initcall_debug, initcall_debug, bool, 0644);
 
 static char msgbuf[64];
-static struct boot_trace_call call;
-static struct boot_trace_ret ret;
 
 int do_one_initcall(initcall_t fn)
 {
        int count = preempt_count();
        ktime_t calltime, delta, rettime;
+       unsigned long long duration;
+       int ret;
 
        if (initcall_debug) {
-               call.caller = task_pid_nr(current);
-               printk("calling  %pF @ %i\n", fn, call.caller);
+               printk("calling  %pF @ %i\n", fn, task_pid_nr(current));
                calltime = ktime_get();
-               trace_boot_call(&call, fn);
-               enable_boot_trace();
        }
 
-       ret.result = fn();
+       ret = fn();
 
        if (initcall_debug) {
-               disable_boot_trace();
                rettime = ktime_get();
                delta = ktime_sub(rettime, calltime);
-               ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10;
-               trace_boot_ret(&ret, fn);
-               printk("initcall %pF returned %d after %Ld usecs\n", fn,
-                       ret.result, ret.duration);
+               duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+               printk("initcall %pF returned %d after %lld usecs\n", fn,
+                       ret, duration);
        }
 
        msgbuf[0] = 0;
 
-       if (ret.result && ret.result != -ENODEV && initcall_debug)
-               sprintf(msgbuf, "error code %d ", ret.result);
+       if (ret && ret != -ENODEV && initcall_debug)
+               sprintf(msgbuf, "error code %d ", ret);
 
        if (preempt_count() != count) {
                strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
@@ -759,7 +762,7 @@ int do_one_initcall(initcall_t fn)
                printk("initcall %pF returned with %s\n", fn, msgbuf);
        }
 
-       return ret.result;
+       return ret;
 }
 
 
@@ -853,6 +856,10 @@ static noinline int init_post(void)
 
 static int __init kernel_init(void * unused)
 {
+       /*
+        * Wait until kthreadd is all set-up.
+        */
+       wait_for_completion(&kthreadd_done);
        lock_kernel();
 
        /*
@@ -878,7 +885,6 @@ static int __init kernel_init(void * unused)
        smp_prepare_cpus(setup_max_cpus);
 
        do_pre_smp_initcalls();
-       start_boot_trace();
 
        smp_init();
        sched_init_smp();