--- linux-2.6.0-test11-base/kernel/sched.c 2003-11-24 22:18:56.000000000 +1100 +++ linux-2.6.0-test11-ht3/kernel/sched.c 2003-12-15 23:38:33.250059542 +1100 @@ -204,6 +204,7 @@ struct runqueue { struct mm_struct *prev_mm; prio_array_t *active, *expired, arrays[2]; int prev_cpu_load[NR_CPUS]; + unsigned long cpu; #ifdef CONFIG_NUMA atomic_t *node_nr_running; int prev_node_load[MAX_NUMNODES]; @@ -221,6 +222,10 @@ static DEFINE_PER_CPU(struct runqueue, r #define task_rq(p) cpu_rq(task_cpu(p)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) +#define ht_active (cpu_has_ht && smp_num_siblings > 1) +#define ht_siblings(cpu1, cpu2) (ht_active && \ + cpu_sibling_map[(cpu1)] == (cpu2)) + /* * Default context-switch locking: */ @@ -1157,8 +1162,9 @@ can_migrate_task(task_t *tsk, runqueue_t { unsigned long delta = sched_clock() - tsk->timestamp; - if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks))) - return 0; + if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)) && + !ht_siblings(this_cpu, task_cpu(tsk))) + return 0; if (task_running(rq, tsk)) return 0; if (!cpu_isset(this_cpu, tsk->cpus_allowed)) @@ -1193,15 +1199,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 (ht_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: */ @@ -1212,9 +1226,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 (ht_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; } @@ -2812,6 +2833,7 @@ void __init sched_init(void) prio_array_t *array; rq = cpu_rq(i); + rq->cpu = (unsigned long)(i); rq->active = rq->arrays; rq->expired = rq->arrays + 1; spin_lock_init(&rq->lock);