UBUNTU: Ubuntu-2.6.38-12.51
[linux-flexiantxendom0-natty.git] / init / main.c
index 86cbfd0..3549e1d 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
@@ -68,6 +67,7 @@
 #include <linux/sfi.h>
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
+#include <linux/perf_event.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -96,6 +96,15 @@ static inline void mark_rodata_ro(void) { }
 extern void tc_init(void);
 #endif
 
+/*
+ * Debug helper: via this flag we know that we are in 'early bootup code'
+ * where only the boot processor is running with IRQ disabled.  This means
+ * two things - IRQ must not be enabled before the flag is cleared and some
+ * operations which are not allowed with IRQ disabled are allowed while the
+ * flag is set.
+ */
+bool early_boot_irqs_disabled __read_mostly;
+
 enum system_states system_state __read_mostly;
 EXPORT_SYMBOL(system_state);
 
@@ -104,6 +113,11 @@ EXPORT_SYMBOL(system_state);
  */
 #define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
 #define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
+#ifdef CONFIG_INIT_PASS_ALL_PARAMS
+#define INIT_PASS_FUNCTION pass_all_bootoptions
+#else
+#define INIT_PASS_FUNCTION pass_unknown_bootoptions
+#endif
 
 extern void time_init(void);
 /* Default late time init is NULL. archs can override this later. */
@@ -197,15 +211,15 @@ static int __init set_reset_devices(char *str)
 
 __setup("reset_devices", set_reset_devices);
 
-static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
+const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 static const char *panic_later, *panic_param;
 
-extern struct obs_kernel_param __setup_start[], __setup_end[];
+extern const struct obs_kernel_param __setup_start[], __setup_end[];
 
 static int __init obsolete_checksetup(char *line)
 {
-       struct obs_kernel_param *p;
+       const struct obs_kernel_param *p;
        int had_early_param = 0;
 
        p = __setup_start;
@@ -248,7 +262,7 @@ static int __init debug_kernel(char *str)
 
 static int __init quiet_kernel(char *str)
 {
-       console_loglevel = 4;
+       console_loglevel = 2;
        return 0;
 }
 
@@ -264,10 +278,11 @@ static int __init loglevel(char *str)
 early_param("loglevel", loglevel);
 
 /*
- * Unknown boot options get handed to init, unless they look like
- * unused parameters (modprobe will find them in /proc/cmdline).
+ * Select boot options to hand to init.  If all is set hand off them all
+ * otherwise only hand off unused ones which do not apply to modules
+ * (modprobe will find them in /proc/cmdline).
  */
-static int __init unknown_bootoption(char *param, char *val)
+static int __init pass_bootoption(char *param, char *val, int all)
 {
        /* Change NUL term back to "=", to make "param" the whole string. */
        if (val) {
@@ -283,11 +298,11 @@ static int __init unknown_bootoption(char *param, char *val)
        }
 
        /* Handle obsolete-style parameters */
-       if (obsolete_checksetup(param))
+       if (obsolete_checksetup(param) && !all)
                return 0;
 
        /* Unused module parameter. */
-       if (strchr(param, '.') && (!val || strchr(param, '.') < val))
+       if (!all && strchr(param, '.') && (!val || strchr(param, '.') < val))
                return 0;
 
        if (panic_later)
@@ -318,6 +333,16 @@ static int __init unknown_bootoption(char *param, char *val)
        }
        return 0;
 }
+static int __init pass_unknown_bootoptions(char *param, char *val, int known)
+{
+       if (known)
+               return 0;
+       return pass_bootoption(param, val, 0);
+}
+static int __init pass_all_bootoptions(char *param, char *val, int known)
+{
+       return pass_bootoption(param, val, 1);
+}
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 int __read_mostly debug_pagealloc_enabled = 0;
@@ -424,7 +449,6 @@ static void __init setup_command_line(char *command_line)
 static __initdata DECLARE_COMPLETION(kthreadd_done);
 
 static noinline void __init_refok rest_init(void)
-       __releases(kernel_lock)
 {
        int pid;
 
@@ -456,9 +480,12 @@ static noinline void __init_refok rest_init(void)
 }
 
 /* Check for early params. */
-static int __init do_early_param(char *param, char *val)
+static int __init do_early_param(char *param, char *val, int known)
 {
-       struct obs_kernel_param *p;
+       const struct obs_kernel_param *p;
+
+       if (known)
+               return 0;
 
        for (p = __setup_start; p < __setup_end; p++) {
                if ((p->early && strcmp(param, p->str) == 0) ||
@@ -536,7 +563,7 @@ static void __init mm_init(void)
 asmlinkage void __init start_kernel(void)
 {
        char * command_line;
-       extern struct kernel_param __start___param[], __stop___param[];
+       extern const struct kernel_param __start___param[], __stop___param[];
 
        smp_setup_processor_id();
 
@@ -555,8 +582,7 @@ asmlinkage void __init start_kernel(void)
        cgroup_init_early();
 
        local_irq_disable();
-       early_boot_irqs_off();
-       early_init_irq_lock_class();
+       early_boot_irqs_disabled = true;
 
 /*
  * Interrupts are still disabled. Do necessary setups, then
@@ -580,7 +606,7 @@ asmlinkage void __init start_kernel(void)
        parse_early_param();
        parse_args("Booting kernel", static_command_line, __start___param,
                   __stop___param - __start___param,
-                  &unknown_bootoption);
+                  &INIT_PASS_FUNCTION);
        /*
         * These use large bootmem allocations and must precede
         * kmem_cache_init()
@@ -606,6 +632,8 @@ asmlinkage void __init start_kernel(void)
                                "enabled *very* early, fixing it\n");
                local_irq_disable();
        }
+       idr_init_cache();
+       perf_event_init();
        rcu_init();
        radix_tree_init();
        /* init some links before init_ISA_irqs() */
@@ -621,7 +649,7 @@ asmlinkage void __init start_kernel(void)
        if (!irqs_disabled())
                printk(KERN_CRIT "start_kernel(): bug: interrupts were "
                                 "enabled early\n");
-       early_boot_irqs_on();
+       early_boot_irqs_disabled = false;
        local_irq_enable();
 
        /* Interrupts are enabled now so all GFP allocations are safe. */
@@ -659,9 +687,8 @@ asmlinkage void __init start_kernel(void)
 #endif
        page_cgroup_init();
        enable_debug_pagealloc();
-       kmemleak_init();
        debug_objects_mem_init();
-       idr_init_cache();
+       kmemleak_init();
        setup_per_cpu_pageset();
        numa_policy_init();
        if (late_time_init)
@@ -778,9 +805,6 @@ static void __init do_initcalls(void)
 
        for (fn = __early_initcall_end; fn < __initcall_end; fn++)
                do_one_initcall(*fn);
-
-       /* Make sure there is no pending stuff from the initcall sequence */
-       flush_scheduled_work();
 }
 
 /*
@@ -809,7 +833,7 @@ static void __init do_pre_smp_initcalls(void)
                do_one_initcall(*fn);
 }
 
-static void run_init_process(char *init_filename)
+static void run_init_process(const char *init_filename)
 {
        argv_init[0] = init_filename;
        kernel_execve(init_filename, argv_init, envp_init);
@@ -819,7 +843,6 @@ static void run_init_process(char *init_filename)
  * makes it inline to init() and it becomes part of init.text section
  */
 static noinline int init_post(void)
-       __releases(kernel_lock)
 {
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();
@@ -886,6 +909,7 @@ static int __init kernel_init(void * unused)
        smp_prepare_cpus(setup_max_cpus);
 
        do_pre_smp_initcalls();
+       lockup_detector_init();
 
        smp_init();
        sched_init_smp();
@@ -899,6 +923,12 @@ static int __init kernel_init(void * unused)
        (void) sys_dup(0);
        (void) sys_dup(0);
        /*
+        * We need to ensure that the filesystem is ready by this point, wait for
+        * async_populate_rootfs to complete.
+        */
+       populate_rootfs_wait();
+
+       /*
         * check if there is an early userspace init.  If yes, let it do all
         * the work
         */