Index: linux-2.6/include/linux/sched.h =================================================================== --- linux-2.6.orig/include/linux/sched.h 2005-10-29 00:52:31.000000000 +1000 +++ linux-2.6/include/linux/sched.h 2005-10-29 00:58:51.000000000 +1000 @@ -648,9 +648,12 @@ struct task_struct { int lock_depth; /* BKL lock depth */ -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) + int last_waker_cpu; /* CPU that last woke this task up */ +#if defined(__ARCH_WANT_UNLOCKED_CTXSW) int oncpu; #endif +#endif int prio, static_prio; struct list_head run_list; prio_array_t *array; Index: linux-2.6/kernel/sched.c =================================================================== --- linux-2.6.orig/kernel/sched.c 2005-10-29 00:52:34.000000000 +1000 +++ linux-2.6/kernel/sched.c 2005-10-29 01:00:53.000000000 +1000 @@ -1183,6 +1183,10 @@ static int try_to_wake_up(task_t *p, uns } } + if (p->last_waker_cpu != this_cpu) + goto out_set_cpu; + + if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) goto out_set_cpu; @@ -1253,6 +1257,8 @@ out_set_cpu: cpu = task_cpu(p); } + p->last_waker_cpu = this_cpu; + out_activate: #endif /* CONFIG_SMP */ if (old_state == TASK_UNINTERRUPTIBLE) { @@ -1334,9 +1340,12 @@ void fastcall sched_fork(task_t *p, int #ifdef CONFIG_SCHEDSTATS memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) + p->last_waker_cpu = cpu; +#if defined(__ARCH_WANT_UNLOCKED_CTXSW) p->oncpu = 0; #endif +#endif #ifdef CONFIG_PREEMPT /* Want to start with kernel preemption disabled. */ p->thread_info->preempt_count = 1;