diff options
Diffstat (limited to 'kernel/sched/fair.c')
-rw-r--r-- | kernel/sched/fair.c | 229 |
1 files changed, 114 insertions, 115 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9a6daf86a76a..2da80a55827b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -4232,36 +4232,6 @@ static unsigned long task_h_load(struct task_struct *p) | |||
4232 | 4232 | ||
4233 | /********** Helpers for find_busiest_group ************************/ | 4233 | /********** Helpers for find_busiest_group ************************/ |
4234 | /* | 4234 | /* |
4235 | * sd_lb_stats - Structure to store the statistics of a sched_domain | ||
4236 | * during load balancing. | ||
4237 | */ | ||
4238 | struct sd_lb_stats { | ||
4239 | struct sched_group *busiest; /* Busiest group in this sd */ | ||
4240 | struct sched_group *this; /* Local group in this sd */ | ||
4241 | unsigned long total_load; /* Total load of all groups in sd */ | ||
4242 | unsigned long total_pwr; /* Total power of all groups in sd */ | ||
4243 | unsigned long avg_load; /* Average load across all groups in sd */ | ||
4244 | |||
4245 | /** Statistics of this group */ | ||
4246 | unsigned long this_load; | ||
4247 | unsigned long this_load_per_task; | ||
4248 | unsigned long this_nr_running; | ||
4249 | unsigned long this_has_capacity; | ||
4250 | unsigned int this_idle_cpus; | ||
4251 | |||
4252 | /* Statistics of the busiest group */ | ||
4253 | unsigned int busiest_idle_cpus; | ||
4254 | unsigned long max_load; | ||
4255 | unsigned long busiest_load_per_task; | ||
4256 | unsigned long busiest_nr_running; | ||
4257 | unsigned long busiest_group_capacity; | ||
4258 | unsigned long busiest_has_capacity; | ||
4259 | unsigned int busiest_group_weight; | ||
4260 | |||
4261 | int group_imb; /* Is there imbalance in this sd */ | ||
4262 | }; | ||
4263 | |||
4264 | /* | ||
4265 | * sg_lb_stats - stats of a sched_group required for load_balancing | 4235 | * sg_lb_stats - stats of a sched_group required for load_balancing |
4266 | */ | 4236 | */ |
4267 | struct sg_lb_stats { | 4237 | struct sg_lb_stats { |
@@ -4269,6 +4239,7 @@ struct sg_lb_stats { | |||
4269 | unsigned long group_load; /* Total load over the CPUs of the group */ | 4239 | unsigned long group_load; /* Total load over the CPUs of the group */ |
4270 | unsigned long sum_nr_running; /* Nr tasks running in the group */ | 4240 | unsigned long sum_nr_running; /* Nr tasks running in the group */ |
4271 | unsigned long sum_weighted_load; /* Weighted load of group's tasks */ | 4241 | unsigned long sum_weighted_load; /* Weighted load of group's tasks */ |
4242 | unsigned long load_per_task; | ||
4272 | unsigned long group_capacity; | 4243 | unsigned long group_capacity; |
4273 | unsigned long idle_cpus; | 4244 | unsigned long idle_cpus; |
4274 | unsigned long group_weight; | 4245 | unsigned long group_weight; |
@@ -4276,6 +4247,21 @@ struct sg_lb_stats { | |||
4276 | int group_has_capacity; /* Is there extra capacity in the group? */ | 4247 | int group_has_capacity; /* Is there extra capacity in the group? */ |
4277 | }; | 4248 | }; |
4278 | 4249 | ||
4250 | /* | ||
4251 | * sd_lb_stats - Structure to store the statistics of a sched_domain | ||
4252 | * during load balancing. | ||
4253 | */ | ||
4254 | struct sd_lb_stats { | ||
4255 | struct sched_group *busiest; /* Busiest group in this sd */ | ||
4256 | struct sched_group *local; /* Local group in this sd */ | ||
4257 | unsigned long total_load; /* Total load of all groups in sd */ | ||
4258 | unsigned long total_pwr; /* Total power of all groups in sd */ | ||
4259 | unsigned long avg_load; /* Average load across all groups in sd */ | ||
4260 | |||
4261 | struct sg_lb_stats local_stat; /* Statistics of the local group */ | ||
4262 | struct sg_lb_stats busiest_stat;/* Statistics of the busiest group */ | ||
4263 | }; | ||
4264 | |||
4279 | /** | 4265 | /** |
4280 | * get_sd_load_idx - Obtain the load index for a given sched domain. | 4266 | * get_sd_load_idx - Obtain the load index for a given sched domain. |
4281 | * @sd: The sched_domain whose load_idx is to be obtained. | 4267 | * @sd: The sched_domain whose load_idx is to be obtained. |
@@ -4490,6 +4476,7 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
4490 | load = target_load(i, load_idx); | 4476 | load = target_load(i, load_idx); |
4491 | } else { | 4477 | } else { |
4492 | load = source_load(i, load_idx); | 4478 | load = source_load(i, load_idx); |
4479 | |||
4493 | if (load > max_cpu_load) | 4480 | if (load > max_cpu_load) |
4494 | max_cpu_load = load; | 4481 | max_cpu_load = load; |
4495 | if (min_cpu_load > load) | 4482 | if (min_cpu_load > load) |
@@ -4531,10 +4518,12 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
4531 | (max_nr_running - min_nr_running) > 1) | 4518 | (max_nr_running - min_nr_running) > 1) |
4532 | sgs->group_imb = 1; | 4519 | sgs->group_imb = 1; |
4533 | 4520 | ||
4534 | sgs->group_capacity = DIV_ROUND_CLOSEST(group->sgp->power, | 4521 | sgs->group_capacity = |
4535 | SCHED_POWER_SCALE); | 4522 | DIV_ROUND_CLOSEST(group->sgp->power, SCHED_POWER_SCALE); |
4523 | |||
4536 | if (!sgs->group_capacity) | 4524 | if (!sgs->group_capacity) |
4537 | sgs->group_capacity = fix_small_capacity(env->sd, group); | 4525 | sgs->group_capacity = fix_small_capacity(env->sd, group); |
4526 | |||
4538 | sgs->group_weight = group->group_weight; | 4527 | sgs->group_weight = group->group_weight; |
4539 | 4528 | ||
4540 | if (sgs->group_capacity > sgs->sum_nr_running) | 4529 | if (sgs->group_capacity > sgs->sum_nr_running) |
@@ -4556,7 +4545,7 @@ static bool update_sd_pick_busiest(struct lb_env *env, | |||
4556 | struct sched_group *sg, | 4545 | struct sched_group *sg, |
4557 | struct sg_lb_stats *sgs) | 4546 | struct sg_lb_stats *sgs) |
4558 | { | 4547 | { |
4559 | if (sgs->avg_load <= sds->max_load) | 4548 | if (sgs->avg_load <= sds->busiest_stat.avg_load) |
4560 | return false; | 4549 | return false; |
4561 | 4550 | ||
4562 | if (sgs->sum_nr_running > sgs->group_capacity) | 4551 | if (sgs->sum_nr_running > sgs->group_capacity) |
@@ -4593,7 +4582,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
4593 | { | 4582 | { |
4594 | struct sched_domain *child = env->sd->child; | 4583 | struct sched_domain *child = env->sd->child; |
4595 | struct sched_group *sg = env->sd->groups; | 4584 | struct sched_group *sg = env->sd->groups; |
4596 | struct sg_lb_stats sgs; | 4585 | struct sg_lb_stats tmp_sgs; |
4597 | int load_idx, prefer_sibling = 0; | 4586 | int load_idx, prefer_sibling = 0; |
4598 | 4587 | ||
4599 | if (child && child->flags & SD_PREFER_SIBLING) | 4588 | if (child && child->flags & SD_PREFER_SIBLING) |
@@ -4602,14 +4591,17 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
4602 | load_idx = get_sd_load_idx(env->sd, env->idle); | 4591 | load_idx = get_sd_load_idx(env->sd, env->idle); |
4603 | 4592 | ||
4604 | do { | 4593 | do { |
4594 | struct sg_lb_stats *sgs = &tmp_sgs; | ||
4605 | int local_group; | 4595 | int local_group; |
4606 | 4596 | ||
4607 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); | 4597 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); |
4608 | memset(&sgs, 0, sizeof(sgs)); | 4598 | if (local_group) { |
4609 | update_sg_lb_stats(env, sg, load_idx, local_group, &sgs); | 4599 | sds->local = sg; |
4600 | sgs = &sds->local_stat; | ||
4601 | } | ||
4610 | 4602 | ||
4611 | sds->total_load += sgs.group_load; | 4603 | memset(sgs, 0, sizeof(*sgs)); |
4612 | sds->total_pwr += sg->sgp->power; | 4604 | update_sg_lb_stats(env, sg, load_idx, local_group, sgs); |
4613 | 4605 | ||
4614 | /* | 4606 | /* |
4615 | * In case the child domain prefers tasks go to siblings | 4607 | * In case the child domain prefers tasks go to siblings |
@@ -4621,26 +4613,17 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
4621 | * heaviest group when it is already under-utilized (possible | 4613 | * heaviest group when it is already under-utilized (possible |
4622 | * with a large weight task outweighs the tasks on the system). | 4614 | * with a large weight task outweighs the tasks on the system). |
4623 | */ | 4615 | */ |
4624 | if (prefer_sibling && !local_group && sds->this_has_capacity) | 4616 | if (prefer_sibling && !local_group && |
4625 | sgs.group_capacity = min(sgs.group_capacity, 1UL); | 4617 | sds->local && sds->local_stat.group_has_capacity) |
4618 | sgs->group_capacity = min(sgs->group_capacity, 1UL); | ||
4626 | 4619 | ||
4627 | if (local_group) { | 4620 | /* Now, start updating sd_lb_stats */ |
4628 | sds->this_load = sgs.avg_load; | 4621 | sds->total_load += sgs->group_load; |
4629 | sds->this = sg; | 4622 | sds->total_pwr += sg->sgp->power; |
4630 | sds->this_nr_running = sgs.sum_nr_running; | 4623 | |
4631 | sds->this_load_per_task = sgs.sum_weighted_load; | 4624 | if (!local_group && update_sd_pick_busiest(env, sds, sg, sgs)) { |
4632 | sds->this_has_capacity = sgs.group_has_capacity; | ||
4633 | sds->this_idle_cpus = sgs.idle_cpus; | ||
4634 | } else if (update_sd_pick_busiest(env, sds, sg, &sgs)) { | ||
4635 | sds->max_load = sgs.avg_load; | ||
4636 | sds->busiest = sg; | 4625 | sds->busiest = sg; |
4637 | sds->busiest_nr_running = sgs.sum_nr_running; | 4626 | sds->busiest_stat = *sgs; |
4638 | sds->busiest_idle_cpus = sgs.idle_cpus; | ||
4639 | sds->busiest_group_capacity = sgs.group_capacity; | ||
4640 | sds->busiest_load_per_task = sgs.sum_weighted_load; | ||
4641 | sds->busiest_has_capacity = sgs.group_has_capacity; | ||
4642 | sds->busiest_group_weight = sgs.group_weight; | ||
4643 | sds->group_imb = sgs.group_imb; | ||
4644 | } | 4627 | } |
4645 | 4628 | ||
4646 | sg = sg->next; | 4629 | sg = sg->next; |
@@ -4684,8 +4667,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds) | |||
4684 | if (env->dst_cpu > busiest_cpu) | 4667 | if (env->dst_cpu > busiest_cpu) |
4685 | return 0; | 4668 | return 0; |
4686 | 4669 | ||
4687 | env->imbalance = DIV_ROUND_CLOSEST( | 4670 | env->imbalance = DIV_ROUND_CLOSEST(sds->busiest_stat.avg_load * |
4688 | sds->max_load * sds->busiest->sgp->power, SCHED_POWER_SCALE); | 4671 | sds->busiest->sgp->power, SCHED_POWER_SCALE); |
4689 | 4672 | ||
4690 | return 1; | 4673 | return 1; |
4691 | } | 4674 | } |
@@ -4703,24 +4686,23 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) | |||
4703 | unsigned long tmp, pwr_now = 0, pwr_move = 0; | 4686 | unsigned long tmp, pwr_now = 0, pwr_move = 0; |
4704 | unsigned int imbn = 2; | 4687 | unsigned int imbn = 2; |
4705 | unsigned long scaled_busy_load_per_task; | 4688 | unsigned long scaled_busy_load_per_task; |
4689 | struct sg_lb_stats *local, *busiest; | ||
4706 | 4690 | ||
4707 | if (sds->this_nr_running) { | 4691 | local = &sds->local_stat; |
4708 | sds->this_load_per_task /= sds->this_nr_running; | 4692 | busiest = &sds->busiest_stat; |
4709 | if (sds->busiest_load_per_task > | ||
4710 | sds->this_load_per_task) | ||
4711 | imbn = 1; | ||
4712 | } else { | ||
4713 | sds->this_load_per_task = | ||
4714 | cpu_avg_load_per_task(env->dst_cpu); | ||
4715 | } | ||
4716 | 4693 | ||
4717 | scaled_busy_load_per_task = sds->busiest_load_per_task | 4694 | if (!local->sum_nr_running) |
4718 | * SCHED_POWER_SCALE; | 4695 | local->load_per_task = cpu_avg_load_per_task(env->dst_cpu); |
4719 | scaled_busy_load_per_task /= sds->busiest->sgp->power; | 4696 | else if (busiest->load_per_task > local->load_per_task) |
4697 | imbn = 1; | ||
4720 | 4698 | ||
4721 | if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= | 4699 | scaled_busy_load_per_task = |
4722 | (scaled_busy_load_per_task * imbn)) { | 4700 | (busiest->load_per_task * SCHED_POWER_SCALE) / |
4723 | env->imbalance = sds->busiest_load_per_task; | 4701 | sds->busiest->sgp->power; |
4702 | |||
4703 | if (busiest->avg_load - local->avg_load + scaled_busy_load_per_task >= | ||
4704 | (scaled_busy_load_per_task * imbn)) { | ||
4705 | env->imbalance = busiest->load_per_task; | ||
4724 | return; | 4706 | return; |
4725 | } | 4707 | } |
4726 | 4708 | ||
@@ -4731,33 +4713,36 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) | |||
4731 | */ | 4713 | */ |
4732 | 4714 | ||
4733 | pwr_now += sds->busiest->sgp->power * | 4715 | pwr_now += sds->busiest->sgp->power * |
4734 | min(sds->busiest_load_per_task, sds->max_load); | 4716 | min(busiest->load_per_task, busiest->avg_load); |
4735 | pwr_now += sds->this->sgp->power * | 4717 | pwr_now += sds->local->sgp->power * |
4736 | min(sds->this_load_per_task, sds->this_load); | 4718 | min(local->load_per_task, local->avg_load); |
4737 | pwr_now /= SCHED_POWER_SCALE; | 4719 | pwr_now /= SCHED_POWER_SCALE; |
4738 | 4720 | ||
4739 | /* Amount of load we'd subtract */ | 4721 | /* Amount of load we'd subtract */ |
4740 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / | 4722 | tmp = (busiest->load_per_task * SCHED_POWER_SCALE) / |
4741 | sds->busiest->sgp->power; | 4723 | sds->busiest->sgp->power; |
4742 | if (sds->max_load > tmp) | 4724 | if (busiest->avg_load > tmp) { |
4743 | pwr_move += sds->busiest->sgp->power * | 4725 | pwr_move += sds->busiest->sgp->power * |
4744 | min(sds->busiest_load_per_task, sds->max_load - tmp); | 4726 | min(busiest->load_per_task, |
4727 | busiest->avg_load - tmp); | ||
4728 | } | ||
4745 | 4729 | ||
4746 | /* Amount of load we'd add */ | 4730 | /* Amount of load we'd add */ |
4747 | if (sds->max_load * sds->busiest->sgp->power < | 4731 | if (busiest->avg_load * sds->busiest->sgp->power < |
4748 | sds->busiest_load_per_task * SCHED_POWER_SCALE) | 4732 | busiest->load_per_task * SCHED_POWER_SCALE) { |
4749 | tmp = (sds->max_load * sds->busiest->sgp->power) / | 4733 | tmp = (busiest->avg_load * sds->busiest->sgp->power) / |
4750 | sds->this->sgp->power; | 4734 | sds->local->sgp->power; |
4751 | else | 4735 | } else { |
4752 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / | 4736 | tmp = (busiest->load_per_task * SCHED_POWER_SCALE) / |
4753 | sds->this->sgp->power; | 4737 | sds->local->sgp->power; |
4754 | pwr_move += sds->this->sgp->power * | 4738 | } |
4755 | min(sds->this_load_per_task, sds->this_load + tmp); | 4739 | pwr_move += sds->local->sgp->power * |
4740 | min(local->load_per_task, local->avg_load + tmp); | ||
4756 | pwr_move /= SCHED_POWER_SCALE; | 4741 | pwr_move /= SCHED_POWER_SCALE; |
4757 | 4742 | ||
4758 | /* Move if we gain throughput */ | 4743 | /* Move if we gain throughput */ |
4759 | if (pwr_move > pwr_now) | 4744 | if (pwr_move > pwr_now) |
4760 | env->imbalance = sds->busiest_load_per_task; | 4745 | env->imbalance = busiest->load_per_task; |
4761 | } | 4746 | } |
4762 | 4747 | ||
4763 | /** | 4748 | /** |
@@ -4769,11 +4754,22 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) | |||
4769 | static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *sds) | 4754 | static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *sds) |
4770 | { | 4755 | { |
4771 | unsigned long max_pull, load_above_capacity = ~0UL; | 4756 | unsigned long max_pull, load_above_capacity = ~0UL; |
4757 | struct sg_lb_stats *local, *busiest; | ||
4758 | |||
4759 | local = &sds->local_stat; | ||
4760 | if (local->sum_nr_running) { | ||
4761 | local->load_per_task = | ||
4762 | local->sum_weighted_load / local->sum_nr_running; | ||
4763 | } | ||
4772 | 4764 | ||
4773 | sds->busiest_load_per_task /= sds->busiest_nr_running; | 4765 | busiest = &sds->busiest_stat; |
4774 | if (sds->group_imb) { | 4766 | /* busiest must have some tasks */ |
4775 | sds->busiest_load_per_task = | 4767 | busiest->load_per_task = |
4776 | min(sds->busiest_load_per_task, sds->avg_load); | 4768 | busiest->sum_weighted_load / busiest->sum_nr_running; |
4769 | |||
4770 | if (busiest->group_imb) { | ||
4771 | busiest->load_per_task = | ||
4772 | min(busiest->load_per_task, sds->avg_load); | ||
4777 | } | 4773 | } |
4778 | 4774 | ||
4779 | /* | 4775 | /* |
@@ -4781,20 +4777,19 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4781 | * max load less than avg load(as we skip the groups at or below | 4777 | * max load less than avg load(as we skip the groups at or below |
4782 | * its cpu_power, while calculating max_load..) | 4778 | * its cpu_power, while calculating max_load..) |
4783 | */ | 4779 | */ |
4784 | if (sds->max_load < sds->avg_load) { | 4780 | if (busiest->avg_load < sds->avg_load) { |
4785 | env->imbalance = 0; | 4781 | env->imbalance = 0; |
4786 | return fix_small_imbalance(env, sds); | 4782 | return fix_small_imbalance(env, sds); |
4787 | } | 4783 | } |
4788 | 4784 | ||
4789 | if (!sds->group_imb) { | 4785 | if (!busiest->group_imb) { |
4790 | /* | 4786 | /* |
4791 | * Don't want to pull so many tasks that a group would go idle. | 4787 | * Don't want to pull so many tasks that a group would go idle. |
4792 | */ | 4788 | */ |
4793 | load_above_capacity = (sds->busiest_nr_running - | 4789 | load_above_capacity = |
4794 | sds->busiest_group_capacity); | 4790 | (busiest->sum_nr_running - busiest->group_capacity); |
4795 | 4791 | ||
4796 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); | 4792 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); |
4797 | |||
4798 | load_above_capacity /= sds->busiest->sgp->power; | 4793 | load_above_capacity /= sds->busiest->sgp->power; |
4799 | } | 4794 | } |
4800 | 4795 | ||
@@ -4808,12 +4803,14 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4808 | * Be careful of negative numbers as they'll appear as very large values | 4803 | * Be careful of negative numbers as they'll appear as very large values |
4809 | * with unsigned longs. | 4804 | * with unsigned longs. |
4810 | */ | 4805 | */ |
4811 | max_pull = min(sds->max_load - sds->avg_load, load_above_capacity); | 4806 | max_pull = min(busiest->avg_load - sds->avg_load, |
4807 | load_above_capacity); | ||
4812 | 4808 | ||
4813 | /* How much load to actually move to equalise the imbalance */ | 4809 | /* How much load to actually move to equalise the imbalance */ |
4814 | env->imbalance = min(max_pull * sds->busiest->sgp->power, | 4810 | env->imbalance = min( |
4815 | (sds->avg_load - sds->this_load) * sds->this->sgp->power) | 4811 | max_pull * sds->busiest->sgp->power, |
4816 | / SCHED_POWER_SCALE; | 4812 | (sds->avg_load - local->avg_load) * sds->local->sgp->power |
4813 | ) / SCHED_POWER_SCALE; | ||
4817 | 4814 | ||
4818 | /* | 4815 | /* |
4819 | * if *imbalance is less than the average load per runnable task | 4816 | * if *imbalance is less than the average load per runnable task |
@@ -4821,9 +4818,8 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4821 | * a think about bumping its value to force at least one task to be | 4818 | * a think about bumping its value to force at least one task to be |
4822 | * moved | 4819 | * moved |
4823 | */ | 4820 | */ |
4824 | if (env->imbalance < sds->busiest_load_per_task) | 4821 | if (env->imbalance < busiest->load_per_task) |
4825 | return fix_small_imbalance(env, sds); | 4822 | return fix_small_imbalance(env, sds); |
4826 | |||
4827 | } | 4823 | } |
4828 | 4824 | ||
4829 | /******* find_busiest_group() helpers end here *********************/ | 4825 | /******* find_busiest_group() helpers end here *********************/ |
@@ -4845,9 +4841,9 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4845 | * return the least loaded group whose CPUs can be | 4841 | * return the least loaded group whose CPUs can be |
4846 | * put to idle by rebalancing its tasks onto our group. | 4842 | * put to idle by rebalancing its tasks onto our group. |
4847 | */ | 4843 | */ |
4848 | static struct sched_group * | 4844 | static struct sched_group *find_busiest_group(struct lb_env *env) |
4849 | find_busiest_group(struct lb_env *env) | ||
4850 | { | 4845 | { |
4846 | struct sg_lb_stats *local, *busiest; | ||
4851 | struct sd_lb_stats sds; | 4847 | struct sd_lb_stats sds; |
4852 | 4848 | ||
4853 | memset(&sds, 0, sizeof(sds)); | 4849 | memset(&sds, 0, sizeof(sds)); |
@@ -4857,13 +4853,15 @@ find_busiest_group(struct lb_env *env) | |||
4857 | * this level. | 4853 | * this level. |
4858 | */ | 4854 | */ |
4859 | update_sd_lb_stats(env, &sds); | 4855 | update_sd_lb_stats(env, &sds); |
4856 | local = &sds.local_stat; | ||
4857 | busiest = &sds.busiest_stat; | ||
4860 | 4858 | ||
4861 | if ((env->idle == CPU_IDLE || env->idle == CPU_NEWLY_IDLE) && | 4859 | if ((env->idle == CPU_IDLE || env->idle == CPU_NEWLY_IDLE) && |
4862 | check_asym_packing(env, &sds)) | 4860 | check_asym_packing(env, &sds)) |
4863 | return sds.busiest; | 4861 | return sds.busiest; |
4864 | 4862 | ||
4865 | /* There is no busy sibling group to pull tasks from */ | 4863 | /* There is no busy sibling group to pull tasks from */ |
4866 | if (!sds.busiest || sds.busiest_nr_running == 0) | 4864 | if (!sds.busiest || busiest->sum_nr_running == 0) |
4867 | goto out_balanced; | 4865 | goto out_balanced; |
4868 | 4866 | ||
4869 | sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr; | 4867 | sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr; |
@@ -4873,26 +4871,26 @@ find_busiest_group(struct lb_env *env) | |||
4873 | * work because they assumes all things are equal, which typically | 4871 | * work because they assumes all things are equal, which typically |
4874 | * isn't true due to cpus_allowed constraints and the like. | 4872 | * isn't true due to cpus_allowed constraints and the like. |
4875 | */ | 4873 | */ |
4876 | if (sds.group_imb) | 4874 | if (busiest->group_imb) |
4877 | goto force_balance; | 4875 | goto force_balance; |
4878 | 4876 | ||
4879 | /* SD_BALANCE_NEWIDLE trumps SMP nice when underutilized */ | 4877 | /* SD_BALANCE_NEWIDLE trumps SMP nice when underutilized */ |
4880 | if (env->idle == CPU_NEWLY_IDLE && sds.this_has_capacity && | 4878 | if (env->idle == CPU_NEWLY_IDLE && local->group_has_capacity && |
4881 | !sds.busiest_has_capacity) | 4879 | !busiest->group_has_capacity) |
4882 | goto force_balance; | 4880 | goto force_balance; |
4883 | 4881 | ||
4884 | /* | 4882 | /* |
4885 | * If the local group is more busy than the selected busiest group | 4883 | * If the local group is more busy than the selected busiest group |
4886 | * don't try and pull any tasks. | 4884 | * don't try and pull any tasks. |
4887 | */ | 4885 | */ |
4888 | if (sds.this_load >= sds.max_load) | 4886 | if (local->avg_load >= busiest->avg_load) |
4889 | goto out_balanced; | 4887 | goto out_balanced; |
4890 | 4888 | ||
4891 | /* | 4889 | /* |
4892 | * Don't pull any tasks if this group is already above the domain | 4890 | * Don't pull any tasks if this group is already above the domain |
4893 | * average load. | 4891 | * average load. |
4894 | */ | 4892 | */ |
4895 | if (sds.this_load >= sds.avg_load) | 4893 | if (local->avg_load >= sds.avg_load) |
4896 | goto out_balanced; | 4894 | goto out_balanced; |
4897 | 4895 | ||
4898 | if (env->idle == CPU_IDLE) { | 4896 | if (env->idle == CPU_IDLE) { |
@@ -4902,15 +4900,16 @@ find_busiest_group(struct lb_env *env) | |||
4902 | * there is no imbalance between this and busiest group | 4900 | * there is no imbalance between this and busiest group |
4903 | * wrt to idle cpu's, it is balanced. | 4901 | * wrt to idle cpu's, it is balanced. |
4904 | */ | 4902 | */ |
4905 | if ((sds.this_idle_cpus <= sds.busiest_idle_cpus + 1) && | 4903 | if ((local->idle_cpus < busiest->idle_cpus) && |
4906 | sds.busiest_nr_running <= sds.busiest_group_weight) | 4904 | busiest->sum_nr_running <= busiest->group_weight) |
4907 | goto out_balanced; | 4905 | goto out_balanced; |
4908 | } else { | 4906 | } else { |
4909 | /* | 4907 | /* |
4910 | * In the CPU_NEWLY_IDLE, CPU_NOT_IDLE cases, use | 4908 | * In the CPU_NEWLY_IDLE, CPU_NOT_IDLE cases, use |
4911 | * imbalance_pct to be conservative. | 4909 | * imbalance_pct to be conservative. |
4912 | */ | 4910 | */ |
4913 | if (100 * sds.max_load <= env->sd->imbalance_pct * sds.this_load) | 4911 | if (100 * busiest->avg_load <= |
4912 | env->sd->imbalance_pct * local->avg_load) | ||
4914 | goto out_balanced; | 4913 | goto out_balanced; |
4915 | } | 4914 | } |
4916 | 4915 | ||