aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2005-06-25 17:57:26 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:43 -0400
commit3dbd5342074a1e570ec84edf859deb9be588006d (patch)
treea5f0aa3f4152b409d9b109766f55020c28bbb9af /kernel
parent245af2c7870bd5940f7bfad19a0a03b32751fbc5 (diff)
[PATCH] sched: multilevel sbe sbf
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> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index e75b301b5340..ef32389ee768 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1319,21 +1319,24 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
1319 sd = tmp; 1319 sd = tmp;
1320 1320
1321 if (sd) { 1321 if (sd) {
1322 cpumask_t span;
1322 int new_cpu; 1323 int new_cpu;
1323 struct sched_group *group; 1324 struct sched_group *group;
1324 1325
1326again:
1325 schedstat_inc(sd, sbf_cnt); 1327 schedstat_inc(sd, sbf_cnt);
1328 span = sd->span;
1326 cpu = task_cpu(p); 1329 cpu = task_cpu(p);
1327 group = find_idlest_group(sd, p, cpu); 1330 group = find_idlest_group(sd, p, cpu);
1328 if (!group) { 1331 if (!group) {
1329 schedstat_inc(sd, sbf_balanced); 1332 schedstat_inc(sd, sbf_balanced);
1330 goto no_forkbalance; 1333 goto nextlevel;
1331 } 1334 }
1332 1335
1333 new_cpu = find_idlest_cpu(group, cpu); 1336 new_cpu = find_idlest_cpu(group, cpu);
1334 if (new_cpu == -1 || new_cpu == cpu) { 1337 if (new_cpu == -1 || new_cpu == cpu) {
1335 schedstat_inc(sd, sbf_balanced); 1338 schedstat_inc(sd, sbf_balanced);
1336 goto no_forkbalance; 1339 goto nextlevel;
1337 } 1340 }
1338 1341
1339 if (cpu_isset(new_cpu, p->cpus_allowed)) { 1342 if (cpu_isset(new_cpu, p->cpus_allowed)) {
@@ -1343,9 +1346,21 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
1343 rq = task_rq_lock(p, &flags); 1346 rq = task_rq_lock(p, &flags);
1344 cpu = task_cpu(p); 1347 cpu = task_cpu(p);
1345 } 1348 }
1349
1350 /* Now try balancing at a lower domain level */
1351nextlevel:
1352 sd = NULL;
1353 for_each_domain(cpu, tmp) {
1354 if (cpus_subset(span, tmp->span))
1355 break;
1356 if (tmp->flags & SD_BALANCE_FORK)
1357 sd = tmp;
1358 }
1359
1360 if (sd)
1361 goto again;
1346 } 1362 }
1347 1363
1348no_forkbalance:
1349#endif 1364#endif
1350 /* 1365 /*
1351 * We decrease the sleep average of forking parents 1366 * We decrease the sleep average of forking parents
@@ -1711,25 +1726,41 @@ void sched_exec(void)
1711 sd = tmp; 1726 sd = tmp;
1712 1727
1713 if (sd) { 1728 if (sd) {
1729 cpumask_t span;
1714 struct sched_group *group; 1730 struct sched_group *group;
1731again:
1715 schedstat_inc(sd, sbe_cnt); 1732 schedstat_inc(sd, sbe_cnt);
1733 span = sd->span;
1716 group = find_idlest_group(sd, current, this_cpu); 1734 group = find_idlest_group(sd, current, this_cpu);
1717 if (!group) { 1735 if (!group) {
1718 schedstat_inc(sd, sbe_balanced); 1736 schedstat_inc(sd, sbe_balanced);
1719 goto out; 1737 goto nextlevel;
1720 } 1738 }
1721 new_cpu = find_idlest_cpu(group, this_cpu); 1739 new_cpu = find_idlest_cpu(group, this_cpu);
1722 if (new_cpu == -1 || new_cpu == this_cpu) { 1740 if (new_cpu == -1 || new_cpu == this_cpu) {
1723 schedstat_inc(sd, sbe_balanced); 1741 schedstat_inc(sd, sbe_balanced);
1724 goto out; 1742 goto nextlevel;
1725 } 1743 }
1726 1744
1727 schedstat_inc(sd, sbe_pushed); 1745 schedstat_inc(sd, sbe_pushed);
1728 put_cpu(); 1746 put_cpu();
1729 sched_migrate_task(current, new_cpu); 1747 sched_migrate_task(current, new_cpu);
1730 return; 1748
1749 /* Now try balancing at a lower domain level */
1750 this_cpu = get_cpu();
1751nextlevel:
1752 sd = NULL;
1753 for_each_domain(this_cpu, tmp) {
1754 if (cpus_subset(span, tmp->span))
1755 break;
1756 if (tmp->flags & SD_BALANCE_EXEC)
1757 sd = tmp;
1758 }
1759
1760 if (sd)
1761 goto again;
1731 } 1762 }
1732out: 1763
1733 put_cpu(); 1764 put_cpu();
1734} 1765}
1735 1766