X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=init%2Fmain.c;h=cd168ebc592439b650042916ab26efd913f7ef42;hb=7d3b56ba37a95f1f370f50258ed3954c304c524b;hp=2a78932f6c075abd36b331db09191b785d3156bc;hpb=71fc47a9adf8ee89e5c96a47222915c5485ac437;p=safe%2Fjmp%2Flinux-2.6 diff --git a/init/main.c b/init/main.c index 2a78932..cd168eb 100644 --- a/init/main.c +++ b/init/main.c @@ -22,15 +22,16 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -51,13 +52,18 @@ #include #include #include +#include #include +#include #include #include #include #include #include #include +#include +#include +#include #include #include @@ -69,23 +75,12 @@ #include #endif -/* - * This is one of the first .c files built. Error out early if we have compiler - * trouble. - */ - -#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0 -#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. -#endif - static int kernel_init(void *); extern void init_IRQ(void); extern void fork_init(unsigned long); extern void mca_init(void); extern void sbus_init(void); -extern void pidhash_init(void); -extern void pidmap_init(void); extern void prio_tree_init(void); extern void radix_tree_init(void); extern void free_initmem(void); @@ -102,12 +97,6 @@ static inline void mark_rodata_ro(void) { } extern void tc_init(void); #endif -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -extern int populate_rootfs(void); -#else -static inline void populate_rootfs(void) {} -#endif - enum system_states system_state; EXPORT_SYMBOL(system_state); @@ -238,30 +227,26 @@ EXPORT_SYMBOL(loops_per_jiffy); static int __init debug_kernel(char *str) { - if (*str) - return 0; console_loglevel = 10; - return 1; + return 0; } static int __init quiet_kernel(char *str) { - if (*str) - return 0; console_loglevel = 4; - return 1; + return 0; } -__setup("debug", debug_kernel); -__setup("quiet", quiet_kernel); +early_param("debug", debug_kernel); +early_param("quiet", quiet_kernel); static int __init loglevel(char *str) { get_option(&str, &console_loglevel); - return 1; + return 0; } -__setup("loglevel=", loglevel); +early_param("loglevel", loglevel); /* * Unknown boot options get handed to init, unless they look like @@ -369,10 +354,26 @@ static void __init smp_init(void) #endif static inline void setup_per_cpu_areas(void) { } +static inline void setup_nr_cpu_ids(void) { } static inline void smp_prepare_cpus(unsigned int maxcpus) { } #else +#if NR_CPUS > BITS_PER_LONG +cpumask_t cpu_mask_all __read_mostly = CPU_MASK_ALL; +EXPORT_SYMBOL(cpu_mask_all); +#endif + +/* Setup number of possible processor ids */ +int nr_cpu_ids __read_mostly = NR_CPUS; +EXPORT_SYMBOL(nr_cpu_ids); + +/* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ +static void __init setup_nr_cpu_ids(void) +{ + nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; +} + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; @@ -401,6 +402,13 @@ static void __init smp_init(void) { unsigned int cpu; + /* + * Set up the current CPU as possible to migrate to. + * The other ones will be done by cpu_up/cpu_down() + */ + cpu = smp_processor_id(); + cpu_set(cpu, cpu_active_map); + /* FIXME: This should be done in userspace --RR */ for_each_present_cpu(cpu) { if (num_online_cpus() >= setup_max_cpus) @@ -447,7 +455,7 @@ static void noinline __init_refok rest_init(void) kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); - kthreadd_task = find_task_by_pid(pid); + kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); unlock_kernel(); /* @@ -505,12 +513,16 @@ static void __init boot_cpu_init(void) { int cpu = smp_processor_id(); /* Mark the boot cpu "present", "online" etc for SMP and UP case */ - cpu_set(cpu, cpu_online_map); - cpu_set(cpu, cpu_present_map); - cpu_set(cpu, cpu_possible_map); + set_cpu_online(cpu, true); + set_cpu_present(cpu, true); + set_cpu_possible(cpu, true); +} + +void __init __weak smp_setup_processor_id(void) +{ } -void __init __attribute__((weak)) smp_setup_processor_id(void) +void __init __weak thread_info_cache_init(void) { } @@ -527,6 +539,7 @@ asmlinkage void __init start_kernel(void) */ unwind_init(); lockdep_init(); + debug_objects_early_init(); cgroup_init_early(); local_irq_disable(); @@ -544,9 +557,11 @@ asmlinkage void __init start_kernel(void) printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); + mm_init_owner(&init_mm, &init_task); setup_command_line(command_line); unwind_setup(); setup_per_cpu_areas(); + setup_nr_cpu_ids(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ /* @@ -562,7 +577,6 @@ asmlinkage void __init start_kernel(void) preempt_disable(); build_all_zonelists(); page_alloc_init(); - enable_debug_pagealloc(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); parse_early_param(); parse_args("Booting kernel", static_command_line, __start___param, @@ -576,6 +590,8 @@ asmlinkage void __init start_kernel(void) sort_main_extable(); trap_init(); rcu_init(); + /* init some links before init_ISA_irqs() */ + early_irq_init(); init_IRQ(); pidhash_init(); init_timers(); @@ -583,6 +599,7 @@ asmlinkage void __init start_kernel(void) softirq_init(); timekeeping_init(); time_init(); + sched_clock_init(); profile_init(); if (!irqs_disabled()) printk("start_kernel(): bug: interrupts were enabled early\n"); @@ -609,17 +626,24 @@ asmlinkage void __init start_kernel(void) #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && - initrd_start < min_low_pfn << PAGE_SHIFT) { + page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " - "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT); + "disabling it.\n", + page_to_pfn(virt_to_page((void *)initrd_start)), + min_low_pfn); initrd_start = 0; } #endif + vmalloc_init(); vfs_caches_init_early(); cpuset_init_early(); + page_cgroup_init(); mem_init(); + enable_debug_pagealloc(); cpu_hotplug_init(); kmem_cache_init(); + debug_objects_mem_init(); + idr_init_cache(); setup_per_cpu_pageset(); numa_policy_init(); if (late_time_init) @@ -633,10 +657,11 @@ asmlinkage void __init start_kernel(void) if (efi_enabled) efi_enter_virtual_mode(); #endif + thread_info_cache_init(); + cred_init(); fork_init(num_physpages); proc_caches_init(); buffer_init(); - unnamed_dev_init(); key_init(); security_init(); vfs_caches_init(num_physpages); @@ -654,79 +679,74 @@ asmlinkage void __init start_kernel(void) check_bugs(); - populate_rootfs(); /* For DSDT override from initramfs */ acpi_early_init(); /* before LAPIC and SMP init */ + ftrace_init(); + /* Do the rest non-__init'ed, we're now alive */ rest_init(); } -static int __initdata initcall_debug; +static int initcall_debug; +core_param(initcall_debug, initcall_debug, bool, 0644); -static int __init initcall_debug_setup(char *str) +int do_one_initcall(initcall_t fn) { - initcall_debug = 1; - return 1; -} -__setup("initcall_debug", initcall_debug_setup); + int count = preempt_count(); + ktime_t calltime, delta, rettime; + char msgbuf[64]; + struct boot_trace_call call; + struct boot_trace_ret ret; + + if (initcall_debug) { + call.caller = task_pid_nr(current); + printk("calling %pF @ %i\n", fn, call.caller); + calltime = ktime_get(); + trace_boot_call(&call, fn); + enable_boot_trace(); + } -extern initcall_t __initcall_start[], __initcall_end[]; + ret.result = fn(); -static void __init do_initcalls(void) -{ - initcall_t *call; - int count = preempt_count(); + 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); + } - for (call = __initcall_start; call < __initcall_end; call++) { - ktime_t t0, t1, delta; - char *msg = NULL; - char msgbuf[40]; - int result; - - if (initcall_debug) { - printk("Calling initcall 0x%p", *call); - print_fn_descriptor_symbol(": %s()", - (unsigned long) *call); - printk("\n"); - t0 = ktime_get(); - } + msgbuf[0] = 0; - result = (*call)(); + if (ret.result && ret.result != -ENODEV && initcall_debug) + sprintf(msgbuf, "error code %d ", ret.result); - if (initcall_debug) { - t1 = ktime_get(); - delta = ktime_sub(t1, t0); + if (preempt_count() != count) { + strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf)); + preempt_count() = count; + } + if (irqs_disabled()) { + strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); + local_irq_enable(); + } + if (msgbuf[0]) { + printk("initcall %pF returned with %s\n", fn, msgbuf); + } - printk("initcall 0x%p", *call); - print_fn_descriptor_symbol(": %s()", - (unsigned long) *call); - printk(" returned %d.\n", result); + return ret.result; +} - printk("initcall 0x%p ran for %Ld msecs: ", - *call, (unsigned long long)delta.tv64 >> 20); - print_fn_descriptor_symbol("%s()\n", - (unsigned long) *call); - } - if (result && result != -ENODEV && initcall_debug) { - sprintf(msgbuf, "error code %d", result); - msg = msgbuf; - } - if (preempt_count() != count) { - msg = "preemption imbalance"; - preempt_count() = count; - } - if (irqs_disabled()) { - msg = "disabled interrupts"; - local_irq_enable(); - } - if (msg) { - printk(KERN_WARNING "initcall at 0x%p", *call); - print_fn_descriptor_symbol(": %s()", - (unsigned long) *call); - printk(": returned with %s\n", msg); - } - } +extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; + +static void __init do_initcalls(void) +{ + initcall_t *call; + + for (call = __early_initcall_end; call < __initcall_end; call++) + do_one_initcall(*call); /* Make sure there is no pending stuff from the initcall sequence */ flush_scheduled_work(); @@ -741,7 +761,7 @@ static void __init do_initcalls(void) */ static void __init do_basic_setup(void) { - /* drivers will send hotplug events */ + rcu_init_sched(); /* needed by module_init stage. */ init_workqueues(); usermodehelper_init(); driver_init(); @@ -749,23 +769,12 @@ static void __init do_basic_setup(void) do_initcalls(); } -static int __initdata nosoftlockup; - -static int __init nosoftlockup_setup(char *str) -{ - nosoftlockup = 1; - return 1; -} -__setup("nosoftlockup", nosoftlockup_setup); - static void __init do_pre_smp_initcalls(void) { - extern int spawn_ksoftirqd(void); + initcall_t *call; - migration_init(); - spawn_ksoftirqd(); - if (!nosoftlockup) - spawn_softlockup_task(); + for (call = __initcall_start; call < __early_initcall_end; call++) + do_one_initcall(*call); } static void run_init_process(char *init_filename) @@ -791,6 +800,8 @@ static int noinline init_post(void) (void) sys_dup(0); (void) sys_dup(0); + current->signal->flags |= SIGNAL_UNKILLABLE; + if (ramdisk_execute_command) { run_init_process(ramdisk_execute_command); printk(KERN_WARNING "Failed to execute %s\n", @@ -822,7 +833,7 @@ static int __init kernel_init(void * unused) /* * init can run on any cpu. */ - set_cpus_allowed(current, CPU_MASK_ALL); + set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR); /* * Tell the world that we're going to be the grim * reaper of innocent orphaned children. @@ -833,12 +844,12 @@ static int __init kernel_init(void * unused) */ init_pid_ns.child_reaper = current; - __set_special_pids(1, 1); cad_pid = task_pid(current); smp_prepare_cpus(setup_max_cpus); do_pre_smp_initcalls(); + start_boot_trace(); smp_init(); sched_init_smp(); @@ -865,6 +876,7 @@ static int __init kernel_init(void * unused) * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ + init_post(); return 0; }