diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 131 |
1 files changed, 70 insertions, 61 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index ec715f97202e..540147e5e82b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3484,6 +3484,71 @@ group_next: | |||
3484 | } while (group != sd->groups); | 3484 | } while (group != sd->groups); |
3485 | 3485 | ||
3486 | } | 3486 | } |
3487 | |||
3488 | /** | ||
3489 | * fix_small_imbalance - Calculate the minor imbalance that exists | ||
3490 | * amongst the groups of a sched_domain, during | ||
3491 | * load balancing. | ||
3492 | * @sds: Statistics of the sched_domain whose imbalance is to be calculated. | ||
3493 | * @this_cpu: The cpu at whose sched_domain we're performing load-balance. | ||
3494 | * @imbalance: Variable to store the imbalance. | ||
3495 | */ | ||
3496 | static inline void fix_small_imbalance(struct sd_lb_stats *sds, | ||
3497 | int this_cpu, unsigned long *imbalance) | ||
3498 | { | ||
3499 | unsigned long tmp, pwr_now = 0, pwr_move = 0; | ||
3500 | unsigned int imbn = 2; | ||
3501 | |||
3502 | if (sds->this_nr_running) { | ||
3503 | sds->this_load_per_task /= sds->this_nr_running; | ||
3504 | if (sds->busiest_load_per_task > | ||
3505 | sds->this_load_per_task) | ||
3506 | imbn = 1; | ||
3507 | } else | ||
3508 | sds->this_load_per_task = | ||
3509 | cpu_avg_load_per_task(this_cpu); | ||
3510 | |||
3511 | if (sds->max_load - sds->this_load + sds->busiest_load_per_task >= | ||
3512 | sds->busiest_load_per_task * imbn) { | ||
3513 | *imbalance = sds->busiest_load_per_task; | ||
3514 | return; | ||
3515 | } | ||
3516 | |||
3517 | /* | ||
3518 | * OK, we don't have enough imbalance to justify moving tasks, | ||
3519 | * however we may be able to increase total CPU power used by | ||
3520 | * moving them. | ||
3521 | */ | ||
3522 | |||
3523 | pwr_now += sds->busiest->__cpu_power * | ||
3524 | min(sds->busiest_load_per_task, sds->max_load); | ||
3525 | pwr_now += sds->this->__cpu_power * | ||
3526 | min(sds->this_load_per_task, sds->this_load); | ||
3527 | pwr_now /= SCHED_LOAD_SCALE; | ||
3528 | |||
3529 | /* Amount of load we'd subtract */ | ||
3530 | tmp = sg_div_cpu_power(sds->busiest, | ||
3531 | sds->busiest_load_per_task * SCHED_LOAD_SCALE); | ||
3532 | if (sds->max_load > tmp) | ||
3533 | pwr_move += sds->busiest->__cpu_power * | ||
3534 | min(sds->busiest_load_per_task, sds->max_load - tmp); | ||
3535 | |||
3536 | /* Amount of load we'd add */ | ||
3537 | if (sds->max_load * sds->busiest->__cpu_power < | ||
3538 | sds->busiest_load_per_task * SCHED_LOAD_SCALE) | ||
3539 | tmp = sg_div_cpu_power(sds->this, | ||
3540 | sds->max_load * sds->busiest->__cpu_power); | ||
3541 | else | ||
3542 | tmp = sg_div_cpu_power(sds->this, | ||
3543 | sds->busiest_load_per_task * SCHED_LOAD_SCALE); | ||
3544 | pwr_move += sds->this->__cpu_power * | ||
3545 | min(sds->this_load_per_task, sds->this_load + tmp); | ||
3546 | pwr_move /= SCHED_LOAD_SCALE; | ||
3547 | |||
3548 | /* Move if we gain throughput */ | ||
3549 | if (pwr_move > pwr_now) | ||
3550 | *imbalance = sds->busiest_load_per_task; | ||
3551 | } | ||
3487 | /******* find_busiest_group() helpers end here *********************/ | 3552 | /******* find_busiest_group() helpers end here *********************/ |
3488 | 3553 | ||
3489 | /* | 3554 | /* |
@@ -3547,7 +3612,8 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
3547 | */ | 3612 | */ |
3548 | if (sds.max_load < sds.avg_load) { | 3613 | if (sds.max_load < sds.avg_load) { |
3549 | *imbalance = 0; | 3614 | *imbalance = 0; |
3550 | goto small_imbalance; | 3615 | fix_small_imbalance(&sds, this_cpu, imbalance); |
3616 | goto ret_busiest; | ||
3551 | } | 3617 | } |
3552 | 3618 | ||
3553 | /* Don't want to pull so many tasks that a group would go idle */ | 3619 | /* Don't want to pull so many tasks that a group would go idle */ |
@@ -3565,67 +3631,10 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
3565 | * a think about bumping its value to force at least one task to be | 3631 | * a think about bumping its value to force at least one task to be |
3566 | * moved | 3632 | * moved |
3567 | */ | 3633 | */ |
3568 | if (*imbalance < sds.busiest_load_per_task) { | 3634 | if (*imbalance < sds.busiest_load_per_task) |
3569 | unsigned long tmp, pwr_now, pwr_move; | 3635 | fix_small_imbalance(&sds, this_cpu, imbalance); |
3570 | unsigned int imbn; | ||
3571 | |||
3572 | small_imbalance: | ||
3573 | pwr_move = pwr_now = 0; | ||
3574 | imbn = 2; | ||
3575 | if (sds.this_nr_running) { | ||
3576 | sds.this_load_per_task /= sds.this_nr_running; | ||
3577 | if (sds.busiest_load_per_task > | ||
3578 | sds.this_load_per_task) | ||
3579 | imbn = 1; | ||
3580 | } else | ||
3581 | sds.this_load_per_task = | ||
3582 | cpu_avg_load_per_task(this_cpu); | ||
3583 | |||
3584 | if (sds.max_load - sds.this_load + | ||
3585 | sds.busiest_load_per_task >= | ||
3586 | sds.busiest_load_per_task * imbn) { | ||
3587 | *imbalance = sds.busiest_load_per_task; | ||
3588 | return sds.busiest; | ||
3589 | } | ||
3590 | |||
3591 | /* | ||
3592 | * OK, we don't have enough imbalance to justify moving tasks, | ||
3593 | * however we may be able to increase total CPU power used by | ||
3594 | * moving them. | ||
3595 | */ | ||
3596 | |||
3597 | pwr_now += sds.busiest->__cpu_power * | ||
3598 | min(sds.busiest_load_per_task, sds.max_load); | ||
3599 | pwr_now += sds.this->__cpu_power * | ||
3600 | min(sds.this_load_per_task, sds.this_load); | ||
3601 | pwr_now /= SCHED_LOAD_SCALE; | ||
3602 | |||
3603 | /* Amount of load we'd subtract */ | ||
3604 | tmp = sg_div_cpu_power(sds.busiest, | ||
3605 | sds.busiest_load_per_task * SCHED_LOAD_SCALE); | ||
3606 | if (sds.max_load > tmp) | ||
3607 | pwr_move += sds.busiest->__cpu_power * | ||
3608 | min(sds.busiest_load_per_task, | ||
3609 | sds.max_load - tmp); | ||
3610 | |||
3611 | /* Amount of load we'd add */ | ||
3612 | if (sds.max_load * sds.busiest->__cpu_power < | ||
3613 | sds.busiest_load_per_task * SCHED_LOAD_SCALE) | ||
3614 | tmp = sg_div_cpu_power(sds.this, | ||
3615 | sds.max_load * sds.busiest->__cpu_power); | ||
3616 | else | ||
3617 | tmp = sg_div_cpu_power(sds.this, | ||
3618 | sds.busiest_load_per_task * SCHED_LOAD_SCALE); | ||
3619 | pwr_move += sds.this->__cpu_power * | ||
3620 | min(sds.this_load_per_task, | ||
3621 | sds.this_load + tmp); | ||
3622 | pwr_move /= SCHED_LOAD_SCALE; | ||
3623 | |||
3624 | /* Move if we gain throughput */ | ||
3625 | if (pwr_move > pwr_now) | ||
3626 | *imbalance = sds.busiest_load_per_task; | ||
3627 | } | ||
3628 | 3636 | ||
3637 | ret_busiest: | ||
3629 | return sds.busiest; | 3638 | return sds.busiest; |
3630 | 3639 | ||
3631 | out_balanced: | 3640 | out_balanced: |