aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
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