diff -u -r linux.orig/include/linux/sched.h linux.new/include/linux/sched.h --- linux.orig/include/linux/sched.h Thu Apr 18 17:44:17 2002 +++ linux.new/include/linux/sched.h Wed May 29 10:56:29 2002 @@ -927,6 +927,19 @@ return res; } +#ifdef CONFIG_SMP + +#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)]) +#define can_schedule(p,cpu) \ + ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu)) + +#else + +#define idle_task(cpu) (&init_task) +#define can_schedule(p,cpu) (1) + +#endif + #endif /* __KERNEL__ */ #endif Only in linux.new/include/linux: sched.h.orig diff -u -r linux.orig/kernel/sched.c linux.new/kernel/sched.c --- linux.orig/kernel/sched.c Tue Apr 30 12:22:02 2002 +++ linux.new/kernel/sched.c Wed May 29 10:56:29 2002 @@ -112,18 +112,7 @@ struct kernel_stat kstat; extern struct task_struct *child_reaper; -#ifdef CONFIG_SMP -#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)]) -#define can_schedule(p,cpu) \ - ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu)) - -#else - -#define idle_task(cpu) (&init_task) -#define can_schedule(p,cpu) (1) - -#endif void scheduling_functions_start_here(void) { } diff -u -r linux.orig/kernel/softirq.c linux.new/kernel/softirq.c --- linux.orig/kernel/softirq.c Wed Oct 31 18:26:02 2001 +++ linux.new/kernel/softirq.c Wed May 29 10:56:59 2002 @@ -60,11 +60,11 @@ asmlinkage void do_softirq() { + extern struct task_struct *child_reaper; int cpu = smp_processor_id(); __u32 pending; long flags; __u32 mask; - if (in_interrupt()) return; @@ -95,7 +95,10 @@ local_irq_disable(); pending = softirq_pending(cpu); - if (pending & mask) { + /* If child reaper!=init_task we have finished the initial bootstrap & haven't received an early softirq */ + /* when the idle_task is the only task running */ + if ((pending && current==idle_task(cpu) && !current->need_resched && child_reaper != &init_task ) + || (pending & mask) ) { mask &= ~pending; goto restart; }