diff -urNp linux-2.5.55-ms-ilb-nba/kernel/sched.c linux-2.5.55-ms-ilb-nbav/kernel/sched.c --- linux-2.5.55-ms-ilb-nba/kernel/sched.c 2003-01-12 18:15:34.000000000 +0100 +++ linux-2.5.55-ms-ilb-nbav/kernel/sched.c 2003-01-12 23:16:25.000000000 +0100 @@ -629,6 +629,9 @@ static inline void double_rq_unlock(runq #if CONFIG_NUMA static atomic_t node_nr_running[MAX_NUMNODES] ____cacheline_maxaligned_in_smp = {[0 ...MAX_NUMNODES-1] = ATOMIC_INIT(0)}; +#define MAX_INTERNODE_LB 40 +#define MIN_INTERNODE_LB 4 +static int internode_lb[MAX_NUMNODES] ____cacheline_maxaligned_in_smp = {[0 ...MAX_NUMNODES-1] = MAX_INTERNODE_LB}; __init void node_nr_running_init(void) { @@ -715,21 +718,31 @@ void sched_balance_exec(void) static int find_busiest_node(int this_node) { int i, node = this_node, load, this_load, maxload; + int avg_load; this_load = maxload = (this_rq()->prev_node_load[this_node] >> 1) + atomic_read(&node_nr_running[this_node]); this_rq()->prev_node_load[this_node] = this_load; + avg_load = this_load; for (i = 0; i < numnodes; i++) { if (i == this_node) continue; load = (this_rq()->prev_node_load[i] >> 1) + atomic_read(&node_nr_running[i]); + avg_load += load; this_rq()->prev_node_load[i] = load; if (load > maxload && (4*load > ((5*4*this_load)/4))) { maxload = load; node = i; } } + avg_load = avg_load / (numnodes ? numnodes : 1); + if (this_load < (avg_load / 2)) { + if (internode_lb[this_node] == MAX_INTERNODE_LB) + internode_lb[this_node] = MIN_INTERNODE_LB; + } else + if (internode_lb[this_node] == MIN_INTERNODE_LB) + internode_lb[this_node] = MAX_INTERNODE_LB; return node; } #endif /* CONFIG_NUMA */ @@ -846,11 +859,10 @@ static inline runqueue_t *find_busiest_q { unsigned long cpumask = __node_to_cpu_mask(__cpu_to_node(this_cpu)); #if CONFIG_NUMA - int node; -# define INTERNODE_LB 10 + int node, this_node = __cpu_to_node(this_cpu); - /* rebalance across nodes only every INTERNODE_LB call */ - if (!(++(this_rq->lb_cntr) % INTERNODE_LB)) { + /* rarely rebalance across nodes */ + if (!(++(this_rq->lb_cntr) % internode_lb[this_node])) { node = find_busiest_node(__cpu_to_node(this_cpu)); cpumask |= __node_to_cpu_mask(node); }