lkml.org 
[lkml]   [2005]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 3/5] sched: multilevel sbe and sbf
3/5
The fundamental problem that Suresh has with balance on exec and fork
is that it only tries to balance the top level domain with the flag
set.

This was worked around by removing degenerate domains, but is still a
problem if people want to start using more complex sched-domains, especially
multilevel NUMA that ia64 is already using.

This patch makes balance on fork and exec try balancing over not just the
top most domain with the flag set, but all the way down the domain tree.

Signed-off-by: Nick Piggin <nickpiggin@yahoo.com.au>

Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c 2005-04-05 16:38:53.000000000 +1000
+++ linux-2.6/kernel/sched.c 2005-04-05 18:39:07.000000000 +1000
@@ -1320,21 +1320,24 @@ void fastcall wake_up_new_task(task_t *
sd = tmp;

if (sd) {
+ cpumask_t span;
int new_cpu;
struct sched_group *group;

+again:
schedstat_inc(sd, sbf_cnt);
+ span = sd->span;
cpu = task_cpu(p);
group = find_idlest_group(sd, p, cpu);
if (!group) {
schedstat_inc(sd, sbf_balanced);
- goto no_forkbalance;
+ goto nextlevel;
}

new_cpu = find_idlest_cpu(group, cpu);
if (new_cpu == -1 || new_cpu == cpu) {
schedstat_inc(sd, sbf_balanced);
- goto no_forkbalance;
+ goto nextlevel;
}

if (cpu_isset(new_cpu, p->cpus_allowed)) {
@@ -1344,9 +1347,21 @@ void fastcall wake_up_new_task(task_t *
rq = task_rq_lock(p, &flags);
cpu = task_cpu(p);
}
+
+ /* Now try balancing at a lower domain level */
+nextlevel:
+ sd = NULL;
+ for_each_domain(cpu, tmp) {
+ if (cpus_subset(span, tmp->span))
+ break;
+ if (tmp->flags & SD_BALANCE_FORK)
+ sd = tmp;
+ }
+
+ if (sd)
+ goto again;
}

-no_forkbalance:
#endif
/*
* We decrease the sleep average of forking parents
@@ -1712,25 +1727,41 @@ void sched_exec(void)
sd = tmp;

if (sd) {
+ cpumask_t span;
struct sched_group *group;
+again:
schedstat_inc(sd, sbe_cnt);
+ span = sd->span;
group = find_idlest_group(sd, current, this_cpu);
if (!group) {
schedstat_inc(sd, sbe_balanced);
- goto out;
+ goto nextlevel;
}
new_cpu = find_idlest_cpu(group, this_cpu);
if (new_cpu == -1 || new_cpu == this_cpu) {
schedstat_inc(sd, sbe_balanced);
- goto out;
+ goto nextlevel;
}

schedstat_inc(sd, sbe_pushed);
put_cpu();
sched_migrate_task(current, new_cpu);
- return;
+
+ /* Now try balancing at a lower domain level */
+ this_cpu = get_cpu();
+nextlevel:
+ sd = NULL;
+ for_each_domain(this_cpu, tmp) {
+ if (cpus_subset(span, tmp->span))
+ break;
+ if (tmp->flags & SD_BALANCE_EXEC)
+ sd = tmp;
+ }
+
+ if (sd)
+ goto again;
}
-out:
+
put_cpu();
}
\
 
 \ /
  Last update: 2005-04-06 13:31    [W:0.107 / U:8.936 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site