diff options
-rw-r--r-- | include/linux/sched.h | 10 | ||||
-rw-r--r-- | kernel/sched.c | 63 |
2 files changed, 44 insertions, 29 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 613491d3a875..36a10781c3f3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -517,10 +517,16 @@ struct sched_domain { | |||
517 | unsigned long alb_failed; | 517 | unsigned long alb_failed; |
518 | unsigned long alb_pushed; | 518 | unsigned long alb_pushed; |
519 | 519 | ||
520 | /* sched_balance_exec() stats */ | 520 | /* SD_BALANCE_EXEC stats */ |
521 | unsigned long sbe_attempts; | 521 | unsigned long sbe_cnt; |
522 | unsigned long sbe_balanced; | ||
522 | unsigned long sbe_pushed; | 523 | unsigned long sbe_pushed; |
523 | 524 | ||
525 | /* SD_BALANCE_FORK stats */ | ||
526 | unsigned long sbf_cnt; | ||
527 | unsigned long sbf_balanced; | ||
528 | unsigned long sbf_pushed; | ||
529 | |||
524 | /* try_to_wake_up() stats */ | 530 | /* try_to_wake_up() stats */ |
525 | unsigned long ttwu_wake_remote; | 531 | unsigned long ttwu_wake_remote; |
526 | unsigned long ttwu_move_affine; | 532 | unsigned long ttwu_move_affine; |
diff --git a/kernel/sched.c b/kernel/sched.c index 7ecc237e2aab..2711130cd973 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -309,7 +309,7 @@ static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags) | |||
309 | * bump this up when changing the output format or the meaning of an existing | 309 | * bump this up when changing the output format or the meaning of an existing |
310 | * format, so that tools can adapt (or abort) | 310 | * format, so that tools can adapt (or abort) |
311 | */ | 311 | */ |
312 | #define SCHEDSTAT_VERSION 11 | 312 | #define SCHEDSTAT_VERSION 12 |
313 | 313 | ||
314 | static int show_schedstat(struct seq_file *seq, void *v) | 314 | static int show_schedstat(struct seq_file *seq, void *v) |
315 | { | 315 | { |
@@ -356,9 +356,10 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
356 | sd->lb_nobusyq[itype], | 356 | sd->lb_nobusyq[itype], |
357 | sd->lb_nobusyg[itype]); | 357 | sd->lb_nobusyg[itype]); |
358 | } | 358 | } |
359 | seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu\n", | 359 | seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", |
360 | sd->alb_cnt, sd->alb_failed, sd->alb_pushed, | 360 | sd->alb_cnt, sd->alb_failed, sd->alb_pushed, |
361 | sd->sbe_pushed, sd->sbe_attempts, | 361 | sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed, |
362 | sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed, | ||
362 | sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance); | 363 | sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance); |
363 | } | 364 | } |
364 | #endif | 365 | #endif |
@@ -1264,24 +1265,34 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) | |||
1264 | sd = tmp; | 1265 | sd = tmp; |
1265 | 1266 | ||
1266 | if (sd) { | 1267 | if (sd) { |
1268 | int new_cpu; | ||
1267 | struct sched_group *group; | 1269 | struct sched_group *group; |
1268 | 1270 | ||
1271 | schedstat_inc(sd, sbf_cnt); | ||
1269 | cpu = task_cpu(p); | 1272 | cpu = task_cpu(p); |
1270 | group = find_idlest_group(sd, p, cpu); | 1273 | group = find_idlest_group(sd, p, cpu); |
1271 | if (group) { | 1274 | if (!group) { |
1272 | int new_cpu; | 1275 | schedstat_inc(sd, sbf_balanced); |
1273 | new_cpu = find_idlest_cpu(group, cpu); | 1276 | goto no_forkbalance; |
1274 | if (new_cpu != -1 && new_cpu != cpu && | 1277 | } |
1275 | cpu_isset(new_cpu, p->cpus_allowed)) { | 1278 | |
1276 | set_task_cpu(p, new_cpu); | 1279 | new_cpu = find_idlest_cpu(group, cpu); |
1277 | task_rq_unlock(rq, &flags); | 1280 | if (new_cpu == -1 || new_cpu == cpu) { |
1278 | rq = task_rq_lock(p, &flags); | 1281 | schedstat_inc(sd, sbf_balanced); |
1279 | cpu = task_cpu(p); | 1282 | goto no_forkbalance; |
1280 | } | 1283 | } |
1284 | |||
1285 | if (cpu_isset(new_cpu, p->cpus_allowed)) { | ||
1286 | schedstat_inc(sd, sbf_pushed); | ||
1287 | set_task_cpu(p, new_cpu); | ||
1288 | task_rq_unlock(rq, &flags); | ||
1289 | rq = task_rq_lock(p, &flags); | ||
1290 | cpu = task_cpu(p); | ||
1281 | } | 1291 | } |
1282 | } | 1292 | } |
1283 | #endif | ||
1284 | 1293 | ||
1294 | no_forkbalance: | ||
1295 | #endif | ||
1285 | /* | 1296 | /* |
1286 | * We decrease the sleep average of forking parents | 1297 | * We decrease the sleep average of forking parents |
1287 | * and children as well, to keep max-interactive tasks | 1298 | * and children as well, to keep max-interactive tasks |
@@ -1618,30 +1629,28 @@ void sched_exec(void) | |||
1618 | struct sched_domain *tmp, *sd = NULL; | 1629 | struct sched_domain *tmp, *sd = NULL; |
1619 | int new_cpu, this_cpu = get_cpu(); | 1630 | int new_cpu, this_cpu = get_cpu(); |
1620 | 1631 | ||
1621 | /* Prefer the current CPU if there's only this task running */ | ||
1622 | if (this_rq()->nr_running <= 1) | ||
1623 | goto out; | ||
1624 | |||
1625 | for_each_domain(this_cpu, tmp) | 1632 | for_each_domain(this_cpu, tmp) |
1626 | if (tmp->flags & SD_BALANCE_EXEC) | 1633 | if (tmp->flags & SD_BALANCE_EXEC) |
1627 | sd = tmp; | 1634 | sd = tmp; |
1628 | 1635 | ||
1629 | if (sd) { | 1636 | if (sd) { |
1630 | struct sched_group *group; | 1637 | struct sched_group *group; |
1631 | schedstat_inc(sd, sbe_attempts); | 1638 | schedstat_inc(sd, sbe_cnt); |
1632 | group = find_idlest_group(sd, current, this_cpu); | 1639 | group = find_idlest_group(sd, current, this_cpu); |
1633 | if (!group) | 1640 | if (!group) { |
1641 | schedstat_inc(sd, sbe_balanced); | ||
1634 | goto out; | 1642 | goto out; |
1643 | } | ||
1635 | new_cpu = find_idlest_cpu(group, this_cpu); | 1644 | new_cpu = find_idlest_cpu(group, this_cpu); |
1636 | if (new_cpu == -1) | 1645 | if (new_cpu == -1 || new_cpu == this_cpu) { |
1646 | schedstat_inc(sd, sbe_balanced); | ||
1637 | goto out; | 1647 | goto out; |
1638 | |||
1639 | if (new_cpu != this_cpu) { | ||
1640 | schedstat_inc(sd, sbe_pushed); | ||
1641 | put_cpu(); | ||
1642 | sched_migrate_task(current, new_cpu); | ||
1643 | return; | ||
1644 | } | 1648 | } |
1649 | |||
1650 | schedstat_inc(sd, sbe_pushed); | ||
1651 | put_cpu(); | ||
1652 | sched_migrate_task(current, new_cpu); | ||
1653 | return; | ||
1645 | } | 1654 | } |
1646 | out: | 1655 | out: |
1647 | put_cpu(); | 1656 | put_cpu(); |