--- linux-2.6.3-ck1pre/kernel/sched.c 2004-02-16 16:35:17.099160238 +1100 +++ linux-2.6.3-ck1/kernel/sched.c 2004-02-16 16:34:21.925816443 +1100 @@ -1294,8 +1294,9 @@ int can_migrate_task(task_t *tsk, runque return 0; if (!cpu_isset(this_cpu, tsk->cpus_allowed)) return 0; - if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks))) - return 0; + if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)) && + !SMT_SIBLINGS(this_cpu, task_cpu(tsk))) + return 0; return 1; } @@ -1327,15 +1328,23 @@ static void load_balance(runqueue_t *thi imbalance /= 2; /* + * For hyperthread siblings take tasks from the active array + * to get cache-warm tasks since they share caches. + */ + if (SMT_SIBLINGS(this_cpu, busiest->cpu)) + array = busiest->active; + /* * We first consider expired tasks. Those will likely not be * executed in the near future, and they are most likely to * be cache-cold, thus switching CPUs has the least effect * on them. */ - if (busiest->expired->nr_active) - array = busiest->expired; - else - array = busiest->active; + else { + if (busiest->expired->nr_active) + array = busiest->expired; + else + array = busiest->active; + } new_array: /* Start searching at priority 0: */ @@ -1346,9 +1355,16 @@ skip_bitmap: else idx = find_next_bit(array->bitmap, MAX_PRIO, idx); if (idx >= MAX_PRIO) { - if (array == busiest->expired) { - array = busiest->active; - goto new_array; + if (SMT_SIBLINGS(this_cpu, busiest->cpu)){ + if (array == busiest->active) { + array = busiest->expired; + goto new_array; + } + } else { + if (array == busiest->expired) { + array = busiest->active; + goto new_array; + } } goto out_unlock; }