Debugging patch to see if we can figure out why some systems fail to boot or initialise hardware correctly. If this fixes a problem for you, PLEASE report it back! Index: linux-2.6.31-bfs/init/main.c =================================================================== --- linux-2.6.31-bfs.orig/init/main.c 2009-09-14 09:33:13.977147049 +1000 +++ linux-2.6.31-bfs/init/main.c 2009-09-14 15:00:57.003282292 +1000 @@ -829,6 +829,8 @@ kernel_execve(init_filename, argv_init, envp_init); } +int fragile_boot __read_mostly = 1; + /* This is a non __init function. Force it to be noinline otherwise gcc * makes it inline to init() and it becomes part of init.text section */ @@ -851,6 +853,9 @@ current->signal->flags |= SIGNAL_UNKILLABLE; + printk(KERN_INFO "Disabling Fragile boot.\n"); + fragile_boot = 0; + if (ramdisk_execute_command) { run_init_process(ramdisk_execute_command); printk(KERN_WARNING "Failed to execute %s\n", Index: linux-2.6.31-bfs/kernel/sched_bfs.c =================================================================== --- linux-2.6.31-bfs.orig/kernel/sched_bfs.c 2009-09-14 09:33:13.997144999 +1000 +++ linux-2.6.31-bfs/kernel/sched_bfs.c 2009-09-14 14:59:33.868278531 +1000 @@ -166,6 +166,7 @@ #ifdef CONFIG_SMP cpumask_t cpu_idle_map; #endif + void (*wunt)(struct task_struct *, struct rq *, unsigned long); }; static struct global_rq grq; @@ -1167,13 +1168,11 @@ * that must be done for every newly created context, then puts the task * on the runqueue and wakes it. */ -void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) +static void +normal_wunt(struct task_struct *p, struct rq *rq, unsigned long clone_flags) { - struct task_struct *parent; - unsigned long flags; - struct rq *rq = time_task_grq_lock(p, &flags); + struct task_struct *parent = p->parent; - parent = p->parent; BUG_ON(p->state != TASK_RUNNING); set_task_cpu(p, task_cpu(parent)); @@ -1190,7 +1189,40 @@ rq->preempt_next = p; } else try_preempt(p, rq); - task_grq_unlock(&flags); +} + +extern int fragile_boot; + +/* Fragile version to not wake to other cpus during boot */ +static void +fb_wunt(struct task_struct *p, struct rq *rq, unsigned long clone_flags) +{ + struct task_struct *parent = p->parent; + + BUG_ON(p->state != TASK_RUNNING); + set_task_cpu(p, task_cpu(parent)); + + activate_task(p, rq); + trace_sched_wakeup_new(rq, p, 1); + /* Child always runs first */ + set_tsk_need_resched(parent); + rq->preempt_next = p; + /* + * fragile_boot is set initially and unset only once just before + * init so we change to normal wunt from here onwards, the ->wunt + * pointer is protected by grq lock. + */ + if (!fragile_boot) + grq.wunt = normal_wunt; +} + +void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) +{ + unsigned long flags; + + struct rq *rq = time_task_grq_lock(p, &flags); + grq.wunt(p, rq, clone_flags); + grq_unlock_irqrestore(&flags); } /* @@ -5937,6 +5969,7 @@ cpus_clear(grq.cpu_idle_map); #endif spin_lock_init(&grq.lock); + grq.wunt = fb_wunt; for_each_possible_cpu(i) { struct rq *rq;