diff options
author | Joonsoo Kim <iamjoonsoo.kim@lge.com> | 2013-08-06 04:36:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-09-02 02:27:34 -0400 |
commit | 23f0d2093c789e612185180c468fa09063834e87 (patch) | |
tree | 63e1fb698d9e4e66d7932f7195af8f94e8f4004b /kernel/sched/fair.c | |
parent | 95a79b805b935f4a7b685aa8a117d916c638323e (diff) |
sched: Factor out code to should_we_balance()
Now checking whether this cpu is appropriate to balance or not
is embedded into update_sg_lb_stats() and this checking has no direct
relationship to this function. There is not enough reason to place
this checking at update_sg_lb_stats(), except saving one iteration
for sched_group_cpus.
In this patch, I factor out this checking to should_we_balance() function.
And before doing actual work for load_balancing, check whether this cpu is
appropriate to balance via should_we_balance(). If this cpu is not
a candidate for balancing, it quit the work immediately.
With this change, we can save two memset cost and can expect better
compiler optimization.
Below is result of this patch.
* Vanilla *
text data bss dec hex filename
34499 1136 116 35751 8ba7 kernel/sched/fair.o
* Patched *
text data bss dec hex filename
34243 1136 116 35495 8aa7 kernel/sched/fair.o
In addition, rename @balance to @continue_balancing in order to represent
its purpose more clearly.
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
[ s/should_balance/continue_balancing/g ]
Reviewed-by: Paul Turner <pjt@google.com>
[ Made style changes and a fix in should_we_balance(). ]
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1375778203-31343-3-git-send-email-iamjoonsoo.kim@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/fair.c')
-rw-r--r-- | kernel/sched/fair.c | 107 |
1 files changed, 53 insertions, 54 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8aa217f62a9e..9a6daf86a76a 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -4463,22 +4463,17 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | |||
4463 | * @group: sched_group whose statistics are to be updated. | 4463 | * @group: sched_group whose statistics are to be updated. |
4464 | * @load_idx: Load index of sched_domain of this_cpu for load calc. | 4464 | * @load_idx: Load index of sched_domain of this_cpu for load calc. |
4465 | * @local_group: Does group contain this_cpu. | 4465 | * @local_group: Does group contain this_cpu. |
4466 | * @balance: Should we balance. | ||
4467 | * @sgs: variable to hold the statistics for this group. | 4466 | * @sgs: variable to hold the statistics for this group. |
4468 | */ | 4467 | */ |
4469 | static inline void update_sg_lb_stats(struct lb_env *env, | 4468 | static inline void update_sg_lb_stats(struct lb_env *env, |
4470 | struct sched_group *group, int load_idx, | 4469 | struct sched_group *group, int load_idx, |
4471 | int local_group, int *balance, struct sg_lb_stats *sgs) | 4470 | int local_group, struct sg_lb_stats *sgs) |
4472 | { | 4471 | { |
4473 | unsigned long nr_running, max_nr_running, min_nr_running; | 4472 | unsigned long nr_running, max_nr_running, min_nr_running; |
4474 | unsigned long load, max_cpu_load, min_cpu_load; | 4473 | unsigned long load, max_cpu_load, min_cpu_load; |
4475 | unsigned int balance_cpu = -1, first_idle_cpu = 0; | ||
4476 | unsigned long avg_load_per_task = 0; | 4474 | unsigned long avg_load_per_task = 0; |
4477 | int i; | 4475 | int i; |
4478 | 4476 | ||
4479 | if (local_group) | ||
4480 | balance_cpu = group_balance_cpu(group); | ||
4481 | |||
4482 | /* Tally up the load of all CPUs in the group */ | 4477 | /* Tally up the load of all CPUs in the group */ |
4483 | max_cpu_load = 0; | 4478 | max_cpu_load = 0; |
4484 | min_cpu_load = ~0UL; | 4479 | min_cpu_load = ~0UL; |
@@ -4492,12 +4487,6 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
4492 | 4487 | ||
4493 | /* Bias balancing toward cpus of our domain */ | 4488 | /* Bias balancing toward cpus of our domain */ |
4494 | if (local_group) { | 4489 | if (local_group) { |
4495 | if (idle_cpu(i) && !first_idle_cpu && | ||
4496 | cpumask_test_cpu(i, sched_group_mask(group))) { | ||
4497 | first_idle_cpu = 1; | ||
4498 | balance_cpu = i; | ||
4499 | } | ||
4500 | |||
4501 | load = target_load(i, load_idx); | 4490 | load = target_load(i, load_idx); |
4502 | } else { | 4491 | } else { |
4503 | load = source_load(i, load_idx); | 4492 | load = source_load(i, load_idx); |
@@ -4519,22 +4508,9 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
4519 | sgs->idle_cpus++; | 4508 | sgs->idle_cpus++; |
4520 | } | 4509 | } |
4521 | 4510 | ||
4522 | /* | 4511 | if (local_group && (env->idle != CPU_NEWLY_IDLE || |
4523 | * First idle cpu or the first cpu(busiest) in this sched group | 4512 | time_after_eq(jiffies, group->sgp->next_update))) |
4524 | * is eligible for doing load balancing at this and above | 4513 | update_group_power(env->sd, env->dst_cpu); |
4525 | * domains. In the newly idle case, we will allow all the cpu's | ||
4526 | * to do the newly idle load balance. | ||
4527 | */ | ||
4528 | if (local_group) { | ||
4529 | if (env->idle != CPU_NEWLY_IDLE) { | ||
4530 | if (balance_cpu != env->dst_cpu) { | ||
4531 | *balance = 0; | ||
4532 | return; | ||
4533 | } | ||
4534 | update_group_power(env->sd, env->dst_cpu); | ||
4535 | } else if (time_after_eq(jiffies, group->sgp->next_update)) | ||
4536 | update_group_power(env->sd, env->dst_cpu); | ||
4537 | } | ||
4538 | 4514 | ||
4539 | /* Adjust by relative CPU power of the group */ | 4515 | /* Adjust by relative CPU power of the group */ |
4540 | sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->sgp->power; | 4516 | sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->sgp->power; |
@@ -4613,7 +4589,7 @@ static bool update_sd_pick_busiest(struct lb_env *env, | |||
4613 | * @sds: variable to hold the statistics for this sched_domain. | 4589 | * @sds: variable to hold the statistics for this sched_domain. |
4614 | */ | 4590 | */ |
4615 | static inline void update_sd_lb_stats(struct lb_env *env, | 4591 | static inline void update_sd_lb_stats(struct lb_env *env, |
4616 | int *balance, struct sd_lb_stats *sds) | 4592 | struct sd_lb_stats *sds) |
4617 | { | 4593 | { |
4618 | struct sched_domain *child = env->sd->child; | 4594 | struct sched_domain *child = env->sd->child; |
4619 | struct sched_group *sg = env->sd->groups; | 4595 | struct sched_group *sg = env->sd->groups; |
@@ -4630,10 +4606,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
4630 | 4606 | ||
4631 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); | 4607 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); |
4632 | memset(&sgs, 0, sizeof(sgs)); | 4608 | memset(&sgs, 0, sizeof(sgs)); |
4633 | update_sg_lb_stats(env, sg, load_idx, local_group, balance, &sgs); | 4609 | update_sg_lb_stats(env, sg, load_idx, local_group, &sgs); |
4634 | |||
4635 | if (local_group && !(*balance)) | ||
4636 | return; | ||
4637 | 4610 | ||
4638 | sds->total_load += sgs.group_load; | 4611 | sds->total_load += sgs.group_load; |
4639 | sds->total_pwr += sg->sgp->power; | 4612 | sds->total_pwr += sg->sgp->power; |
@@ -4866,8 +4839,6 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4866 | * to restore balance. | 4839 | * to restore balance. |
4867 | * | 4840 | * |
4868 | * @env: The load balancing environment. | 4841 | * @env: The load balancing environment. |
4869 | * @balance: Pointer to a variable indicating if this_cpu | ||
4870 | * is the appropriate cpu to perform load balancing at this_level. | ||
4871 | * | 4842 | * |
4872 | * Returns: - the busiest group if imbalance exists. | 4843 | * Returns: - the busiest group if imbalance exists. |
4873 | * - If no imbalance and user has opted for power-savings balance, | 4844 | * - If no imbalance and user has opted for power-savings balance, |
@@ -4875,7 +4846,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4875 | * put to idle by rebalancing its tasks onto our group. | 4846 | * put to idle by rebalancing its tasks onto our group. |
4876 | */ | 4847 | */ |
4877 | static struct sched_group * | 4848 | static struct sched_group * |
4878 | find_busiest_group(struct lb_env *env, int *balance) | 4849 | find_busiest_group(struct lb_env *env) |
4879 | { | 4850 | { |
4880 | struct sd_lb_stats sds; | 4851 | struct sd_lb_stats sds; |
4881 | 4852 | ||
@@ -4885,14 +4856,7 @@ find_busiest_group(struct lb_env *env, int *balance) | |||
4885 | * Compute the various statistics relavent for load balancing at | 4856 | * Compute the various statistics relavent for load balancing at |
4886 | * this level. | 4857 | * this level. |
4887 | */ | 4858 | */ |
4888 | update_sd_lb_stats(env, balance, &sds); | 4859 | update_sd_lb_stats(env, &sds); |
4889 | |||
4890 | /* | ||
4891 | * this_cpu is not the appropriate cpu to perform load balancing at | ||
4892 | * this level. | ||
4893 | */ | ||
4894 | if (!(*balance)) | ||
4895 | goto ret; | ||
4896 | 4860 | ||
4897 | if ((env->idle == CPU_IDLE || env->idle == CPU_NEWLY_IDLE) && | 4861 | if ((env->idle == CPU_IDLE || env->idle == CPU_NEWLY_IDLE) && |
4898 | check_asym_packing(env, &sds)) | 4862 | check_asym_packing(env, &sds)) |
@@ -4956,7 +4920,6 @@ force_balance: | |||
4956 | return sds.busiest; | 4920 | return sds.busiest; |
4957 | 4921 | ||
4958 | out_balanced: | 4922 | out_balanced: |
4959 | ret: | ||
4960 | env->imbalance = 0; | 4923 | env->imbalance = 0; |
4961 | return NULL; | 4924 | return NULL; |
4962 | } | 4925 | } |
@@ -5043,13 +5006,47 @@ static int need_active_balance(struct lb_env *env) | |||
5043 | 5006 | ||
5044 | static int active_load_balance_cpu_stop(void *data); | 5007 | static int active_load_balance_cpu_stop(void *data); |
5045 | 5008 | ||
5009 | static int should_we_balance(struct lb_env *env) | ||
5010 | { | ||
5011 | struct sched_group *sg = env->sd->groups; | ||
5012 | struct cpumask *sg_cpus, *sg_mask; | ||
5013 | int cpu, balance_cpu = -1; | ||
5014 | |||
5015 | /* | ||
5016 | * In the newly idle case, we will allow all the cpu's | ||
5017 | * to do the newly idle load balance. | ||
5018 | */ | ||
5019 | if (env->idle == CPU_NEWLY_IDLE) | ||
5020 | return 1; | ||
5021 | |||
5022 | sg_cpus = sched_group_cpus(sg); | ||
5023 | sg_mask = sched_group_mask(sg); | ||
5024 | /* Try to find first idle cpu */ | ||
5025 | for_each_cpu_and(cpu, sg_cpus, env->cpus) { | ||
5026 | if (!cpumask_test_cpu(cpu, sg_mask) || !idle_cpu(cpu)) | ||
5027 | continue; | ||
5028 | |||
5029 | balance_cpu = cpu; | ||
5030 | break; | ||
5031 | } | ||
5032 | |||
5033 | if (balance_cpu == -1) | ||
5034 | balance_cpu = group_balance_cpu(sg); | ||
5035 | |||
5036 | /* | ||
5037 | * First idle cpu or the first cpu(busiest) in this sched group | ||
5038 | * is eligible for doing load balancing at this and above domains. | ||
5039 | */ | ||
5040 | return balance_cpu != env->dst_cpu; | ||
5041 | } | ||
5042 | |||
5046 | /* | 5043 | /* |
5047 | * Check this_cpu to ensure it is balanced within domain. Attempt to move | 5044 | * Check this_cpu to ensure it is balanced within domain. Attempt to move |
5048 | * tasks if there is an imbalance. | 5045 | * tasks if there is an imbalance. |
5049 | */ | 5046 | */ |
5050 | static int load_balance(int this_cpu, struct rq *this_rq, | 5047 | static int load_balance(int this_cpu, struct rq *this_rq, |
5051 | struct sched_domain *sd, enum cpu_idle_type idle, | 5048 | struct sched_domain *sd, enum cpu_idle_type idle, |
5052 | int *balance) | 5049 | int *continue_balancing) |
5053 | { | 5050 | { |
5054 | int ld_moved, cur_ld_moved, active_balance = 0; | 5051 | int ld_moved, cur_ld_moved, active_balance = 0; |
5055 | struct sched_group *group; | 5052 | struct sched_group *group; |
@@ -5079,11 +5076,12 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
5079 | schedstat_inc(sd, lb_count[idle]); | 5076 | schedstat_inc(sd, lb_count[idle]); |
5080 | 5077 | ||
5081 | redo: | 5078 | redo: |
5082 | group = find_busiest_group(&env, balance); | 5079 | if (!should_we_balance(&env)) { |
5083 | 5080 | *continue_balancing = 0; | |
5084 | if (*balance == 0) | ||
5085 | goto out_balanced; | 5081 | goto out_balanced; |
5082 | } | ||
5086 | 5083 | ||
5084 | group = find_busiest_group(&env); | ||
5087 | if (!group) { | 5085 | if (!group) { |
5088 | schedstat_inc(sd, lb_nobusyg[idle]); | 5086 | schedstat_inc(sd, lb_nobusyg[idle]); |
5089 | goto out_balanced; | 5087 | goto out_balanced; |
@@ -5296,7 +5294,7 @@ void idle_balance(int this_cpu, struct rq *this_rq) | |||
5296 | rcu_read_lock(); | 5294 | rcu_read_lock(); |
5297 | for_each_domain(this_cpu, sd) { | 5295 | for_each_domain(this_cpu, sd) { |
5298 | unsigned long interval; | 5296 | unsigned long interval; |
5299 | int balance = 1; | 5297 | int continue_balancing = 1; |
5300 | 5298 | ||
5301 | if (!(sd->flags & SD_LOAD_BALANCE)) | 5299 | if (!(sd->flags & SD_LOAD_BALANCE)) |
5302 | continue; | 5300 | continue; |
@@ -5304,7 +5302,8 @@ void idle_balance(int this_cpu, struct rq *this_rq) | |||
5304 | if (sd->flags & SD_BALANCE_NEWIDLE) { | 5302 | if (sd->flags & SD_BALANCE_NEWIDLE) { |
5305 | /* If we've pulled tasks over stop searching: */ | 5303 | /* If we've pulled tasks over stop searching: */ |
5306 | pulled_task = load_balance(this_cpu, this_rq, | 5304 | pulled_task = load_balance(this_cpu, this_rq, |
5307 | sd, CPU_NEWLY_IDLE, &balance); | 5305 | sd, CPU_NEWLY_IDLE, |
5306 | &continue_balancing); | ||
5308 | } | 5307 | } |
5309 | 5308 | ||
5310 | interval = msecs_to_jiffies(sd->balance_interval); | 5309 | interval = msecs_to_jiffies(sd->balance_interval); |
@@ -5542,7 +5541,7 @@ void update_max_interval(void) | |||
5542 | */ | 5541 | */ |
5543 | static void rebalance_domains(int cpu, enum cpu_idle_type idle) | 5542 | static void rebalance_domains(int cpu, enum cpu_idle_type idle) |
5544 | { | 5543 | { |
5545 | int balance = 1; | 5544 | int continue_balancing = 1; |
5546 | struct rq *rq = cpu_rq(cpu); | 5545 | struct rq *rq = cpu_rq(cpu); |
5547 | unsigned long interval; | 5546 | unsigned long interval; |
5548 | struct sched_domain *sd; | 5547 | struct sched_domain *sd; |
@@ -5574,7 +5573,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) | |||
5574 | } | 5573 | } |
5575 | 5574 | ||
5576 | if (time_after_eq(jiffies, sd->last_balance + interval)) { | 5575 | if (time_after_eq(jiffies, sd->last_balance + interval)) { |
5577 | if (load_balance(cpu, rq, sd, idle, &balance)) { | 5576 | if (load_balance(cpu, rq, sd, idle, &continue_balancing)) { |
5578 | /* | 5577 | /* |
5579 | * The LBF_SOME_PINNED logic could have changed | 5578 | * The LBF_SOME_PINNED logic could have changed |
5580 | * env->dst_cpu, so we can't know our idle | 5579 | * env->dst_cpu, so we can't know our idle |
@@ -5597,7 +5596,7 @@ out: | |||
5597 | * CPU in our sched group which is doing load balancing more | 5596 | * CPU in our sched group which is doing load balancing more |
5598 | * actively. | 5597 | * actively. |
5599 | */ | 5598 | */ |
5600 | if (!balance) | 5599 | if (!continue_balancing) |
5601 | break; | 5600 | break; |
5602 | } | 5601 | } |
5603 | rcu_read_unlock(); | 5602 | rcu_read_unlock(); |