diff options
author | Nikhil Rao <ncrao@google.com> | 2011-05-18 13:09:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-05-20 08:16:50 -0400 |
commit | 1399fa7807a1a5998bbf147e80668e9950661dfa (patch) | |
tree | dc4e1a97f50b8e7297c82f63e1ad2b15430b33d9 | |
parent | f05998d4b80632f2cc00f108da503066ef5d38d5 (diff) |
sched: Introduce SCHED_POWER_SCALE to scale cpu_power calculations
SCHED_LOAD_SCALE is used to increase nice resolution and to
scale cpu_power calculations in the scheduler. This patch
introduces SCHED_POWER_SCALE and converts all uses of
SCHED_LOAD_SCALE for scaling cpu_power to use SCHED_POWER_SCALE
instead.
This is a preparatory patch for increasing the resolution of
SCHED_LOAD_SCALE, and there is no need to increase resolution
for cpu_power calculations.
Signed-off-by: Nikhil Rao <ncrao@google.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Nikunj A. Dadhania <nikunj@linux.vnet.ibm.com>
Cc: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Cc: Stephan Barwolf <stephan.baerwolf@tu-ilmenau.de>
Cc: Mike Galbraith <efault@gmx.de>
Link: http://lkml.kernel.org/r/1305738580-9924-3-git-send-email-ncrao@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/linux/sched.h | 13 | ||||
-rw-r--r-- | kernel/sched.c | 4 | ||||
-rw-r--r-- | kernel/sched_fair.c | 52 |
3 files changed, 37 insertions, 32 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 12211e1666e2..f2f440221b70 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -788,17 +788,20 @@ enum cpu_idle_type { | |||
788 | }; | 788 | }; |
789 | 789 | ||
790 | /* | 790 | /* |
791 | * sched-domains (multiprocessor balancing) declarations: | ||
792 | */ | ||
793 | |||
794 | /* | ||
795 | * Increase resolution of nice-level calculations: | 791 | * Increase resolution of nice-level calculations: |
796 | */ | 792 | */ |
797 | #define SCHED_LOAD_SHIFT 10 | 793 | #define SCHED_LOAD_SHIFT 10 |
798 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) | 794 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) |
799 | 795 | ||
800 | #define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE | 796 | /* |
797 | * Increase resolution of cpu_power calculations | ||
798 | */ | ||
799 | #define SCHED_POWER_SHIFT 10 | ||
800 | #define SCHED_POWER_SCALE (1L << SCHED_POWER_SHIFT) | ||
801 | 801 | ||
802 | /* | ||
803 | * sched-domains (multiprocessor balancing) declarations: | ||
804 | */ | ||
802 | #ifdef CONFIG_SMP | 805 | #ifdef CONFIG_SMP |
803 | #define SD_LOAD_BALANCE 0x0001 /* Do load balancing on this domain. */ | 806 | #define SD_LOAD_BALANCE 0x0001 /* Do load balancing on this domain. */ |
804 | #define SD_BALANCE_NEWIDLE 0x0002 /* Balance when about to become idle */ | 807 | #define SD_BALANCE_NEWIDLE 0x0002 /* Balance when about to become idle */ |
diff --git a/kernel/sched.c b/kernel/sched.c index d036048b59a4..375e9c677d58 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -6530,7 +6530,7 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, | |||
6530 | cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); | 6530 | cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); |
6531 | 6531 | ||
6532 | printk(KERN_CONT " %s", str); | 6532 | printk(KERN_CONT " %s", str); |
6533 | if (group->cpu_power != SCHED_LOAD_SCALE) { | 6533 | if (group->cpu_power != SCHED_POWER_SCALE) { |
6534 | printk(KERN_CONT " (cpu_power = %d)", | 6534 | printk(KERN_CONT " (cpu_power = %d)", |
6535 | group->cpu_power); | 6535 | group->cpu_power); |
6536 | } | 6536 | } |
@@ -7905,7 +7905,7 @@ void __init sched_init(void) | |||
7905 | #ifdef CONFIG_SMP | 7905 | #ifdef CONFIG_SMP |
7906 | rq->sd = NULL; | 7906 | rq->sd = NULL; |
7907 | rq->rd = NULL; | 7907 | rq->rd = NULL; |
7908 | rq->cpu_power = SCHED_LOAD_SCALE; | 7908 | rq->cpu_power = SCHED_POWER_SCALE; |
7909 | rq->post_schedule = 0; | 7909 | rq->post_schedule = 0; |
7910 | rq->active_balance = 0; | 7910 | rq->active_balance = 0; |
7911 | rq->next_balance = jiffies; | 7911 | rq->next_balance = jiffies; |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 37f22626225e..e32a9b70ee9c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -1584,7 +1584,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, | |||
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | /* Adjust by relative CPU power of the group */ | 1586 | /* Adjust by relative CPU power of the group */ |
1587 | avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power; | 1587 | avg_load = (avg_load * SCHED_POWER_SCALE) / group->cpu_power; |
1588 | 1588 | ||
1589 | if (local_group) { | 1589 | if (local_group) { |
1590 | this_load = avg_load; | 1590 | this_load = avg_load; |
@@ -1722,7 +1722,7 @@ select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags) | |||
1722 | nr_running += cpu_rq(i)->cfs.nr_running; | 1722 | nr_running += cpu_rq(i)->cfs.nr_running; |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE); | 1725 | capacity = DIV_ROUND_CLOSEST(power, SCHED_POWER_SCALE); |
1726 | 1726 | ||
1727 | if (tmp->flags & SD_POWERSAVINGS_BALANCE) | 1727 | if (tmp->flags & SD_POWERSAVINGS_BALANCE) |
1728 | nr_running /= 2; | 1728 | nr_running /= 2; |
@@ -2570,7 +2570,7 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds, | |||
2570 | 2570 | ||
2571 | unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu) | 2571 | unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu) |
2572 | { | 2572 | { |
2573 | return SCHED_LOAD_SCALE; | 2573 | return SCHED_POWER_SCALE; |
2574 | } | 2574 | } |
2575 | 2575 | ||
2576 | unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu) | 2576 | unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu) |
@@ -2607,10 +2607,10 @@ unsigned long scale_rt_power(int cpu) | |||
2607 | available = total - rq->rt_avg; | 2607 | available = total - rq->rt_avg; |
2608 | } | 2608 | } |
2609 | 2609 | ||
2610 | if (unlikely((s64)total < SCHED_LOAD_SCALE)) | 2610 | if (unlikely((s64)total < SCHED_POWER_SCALE)) |
2611 | total = SCHED_LOAD_SCALE; | 2611 | total = SCHED_POWER_SCALE; |
2612 | 2612 | ||
2613 | total >>= SCHED_LOAD_SHIFT; | 2613 | total >>= SCHED_POWER_SHIFT; |
2614 | 2614 | ||
2615 | return div_u64(available, total); | 2615 | return div_u64(available, total); |
2616 | } | 2616 | } |
@@ -2618,7 +2618,7 @@ unsigned long scale_rt_power(int cpu) | |||
2618 | static void update_cpu_power(struct sched_domain *sd, int cpu) | 2618 | static void update_cpu_power(struct sched_domain *sd, int cpu) |
2619 | { | 2619 | { |
2620 | unsigned long weight = sd->span_weight; | 2620 | unsigned long weight = sd->span_weight; |
2621 | unsigned long power = SCHED_LOAD_SCALE; | 2621 | unsigned long power = SCHED_POWER_SCALE; |
2622 | struct sched_group *sdg = sd->groups; | 2622 | struct sched_group *sdg = sd->groups; |
2623 | 2623 | ||
2624 | if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) { | 2624 | if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) { |
@@ -2627,7 +2627,7 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) | |||
2627 | else | 2627 | else |
2628 | power *= default_scale_smt_power(sd, cpu); | 2628 | power *= default_scale_smt_power(sd, cpu); |
2629 | 2629 | ||
2630 | power >>= SCHED_LOAD_SHIFT; | 2630 | power >>= SCHED_POWER_SHIFT; |
2631 | } | 2631 | } |
2632 | 2632 | ||
2633 | sdg->cpu_power_orig = power; | 2633 | sdg->cpu_power_orig = power; |
@@ -2637,10 +2637,10 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) | |||
2637 | else | 2637 | else |
2638 | power *= default_scale_freq_power(sd, cpu); | 2638 | power *= default_scale_freq_power(sd, cpu); |
2639 | 2639 | ||
2640 | power >>= SCHED_LOAD_SHIFT; | 2640 | power >>= SCHED_POWER_SHIFT; |
2641 | 2641 | ||
2642 | power *= scale_rt_power(cpu); | 2642 | power *= scale_rt_power(cpu); |
2643 | power >>= SCHED_LOAD_SHIFT; | 2643 | power >>= SCHED_POWER_SHIFT; |
2644 | 2644 | ||
2645 | if (!power) | 2645 | if (!power) |
2646 | power = 1; | 2646 | power = 1; |
@@ -2682,7 +2682,7 @@ static inline int | |||
2682 | fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | 2682 | fix_small_capacity(struct sched_domain *sd, struct sched_group *group) |
2683 | { | 2683 | { |
2684 | /* | 2684 | /* |
2685 | * Only siblings can have significantly less than SCHED_LOAD_SCALE | 2685 | * Only siblings can have significantly less than SCHED_POWER_SCALE |
2686 | */ | 2686 | */ |
2687 | if (!(sd->flags & SD_SHARE_CPUPOWER)) | 2687 | if (!(sd->flags & SD_SHARE_CPUPOWER)) |
2688 | return 0; | 2688 | return 0; |
@@ -2770,7 +2770,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, | |||
2770 | } | 2770 | } |
2771 | 2771 | ||
2772 | /* Adjust by relative CPU power of the group */ | 2772 | /* Adjust by relative CPU power of the group */ |
2773 | sgs->avg_load = (sgs->group_load * SCHED_LOAD_SCALE) / group->cpu_power; | 2773 | sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->cpu_power; |
2774 | 2774 | ||
2775 | /* | 2775 | /* |
2776 | * Consider the group unbalanced when the imbalance is larger | 2776 | * Consider the group unbalanced when the imbalance is larger |
@@ -2787,7 +2787,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, | |||
2787 | if ((max_cpu_load - min_cpu_load) >= avg_load_per_task && max_nr_running > 1) | 2787 | if ((max_cpu_load - min_cpu_load) >= avg_load_per_task && max_nr_running > 1) |
2788 | sgs->group_imb = 1; | 2788 | sgs->group_imb = 1; |
2789 | 2789 | ||
2790 | sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, SCHED_LOAD_SCALE); | 2790 | sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, |
2791 | SCHED_POWER_SCALE); | ||
2791 | if (!sgs->group_capacity) | 2792 | if (!sgs->group_capacity) |
2792 | sgs->group_capacity = fix_small_capacity(sd, group); | 2793 | sgs->group_capacity = fix_small_capacity(sd, group); |
2793 | sgs->group_weight = group->group_weight; | 2794 | sgs->group_weight = group->group_weight; |
@@ -2961,7 +2962,7 @@ static int check_asym_packing(struct sched_domain *sd, | |||
2961 | return 0; | 2962 | return 0; |
2962 | 2963 | ||
2963 | *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->cpu_power, | 2964 | *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->cpu_power, |
2964 | SCHED_LOAD_SCALE); | 2965 | SCHED_POWER_SCALE); |
2965 | return 1; | 2966 | return 1; |
2966 | } | 2967 | } |
2967 | 2968 | ||
@@ -2990,7 +2991,7 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, | |||
2990 | cpu_avg_load_per_task(this_cpu); | 2991 | cpu_avg_load_per_task(this_cpu); |
2991 | 2992 | ||
2992 | scaled_busy_load_per_task = sds->busiest_load_per_task | 2993 | scaled_busy_load_per_task = sds->busiest_load_per_task |
2993 | * SCHED_LOAD_SCALE; | 2994 | * SCHED_POWER_SCALE; |
2994 | scaled_busy_load_per_task /= sds->busiest->cpu_power; | 2995 | scaled_busy_load_per_task /= sds->busiest->cpu_power; |
2995 | 2996 | ||
2996 | if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= | 2997 | if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= |
@@ -3009,10 +3010,10 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, | |||
3009 | min(sds->busiest_load_per_task, sds->max_load); | 3010 | min(sds->busiest_load_per_task, sds->max_load); |
3010 | pwr_now += sds->this->cpu_power * | 3011 | pwr_now += sds->this->cpu_power * |
3011 | min(sds->this_load_per_task, sds->this_load); | 3012 | min(sds->this_load_per_task, sds->this_load); |
3012 | pwr_now /= SCHED_LOAD_SCALE; | 3013 | pwr_now /= SCHED_POWER_SCALE; |
3013 | 3014 | ||
3014 | /* Amount of load we'd subtract */ | 3015 | /* Amount of load we'd subtract */ |
3015 | tmp = (sds->busiest_load_per_task * SCHED_LOAD_SCALE) / | 3016 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / |
3016 | sds->busiest->cpu_power; | 3017 | sds->busiest->cpu_power; |
3017 | if (sds->max_load > tmp) | 3018 | if (sds->max_load > tmp) |
3018 | pwr_move += sds->busiest->cpu_power * | 3019 | pwr_move += sds->busiest->cpu_power * |
@@ -3020,15 +3021,15 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, | |||
3020 | 3021 | ||
3021 | /* Amount of load we'd add */ | 3022 | /* Amount of load we'd add */ |
3022 | if (sds->max_load * sds->busiest->cpu_power < | 3023 | if (sds->max_load * sds->busiest->cpu_power < |
3023 | sds->busiest_load_per_task * SCHED_LOAD_SCALE) | 3024 | sds->busiest_load_per_task * SCHED_POWER_SCALE) |
3024 | tmp = (sds->max_load * sds->busiest->cpu_power) / | 3025 | tmp = (sds->max_load * sds->busiest->cpu_power) / |
3025 | sds->this->cpu_power; | 3026 | sds->this->cpu_power; |
3026 | else | 3027 | else |
3027 | tmp = (sds->busiest_load_per_task * SCHED_LOAD_SCALE) / | 3028 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / |
3028 | sds->this->cpu_power; | 3029 | sds->this->cpu_power; |
3029 | pwr_move += sds->this->cpu_power * | 3030 | pwr_move += sds->this->cpu_power * |
3030 | min(sds->this_load_per_task, sds->this_load + tmp); | 3031 | min(sds->this_load_per_task, sds->this_load + tmp); |
3031 | pwr_move /= SCHED_LOAD_SCALE; | 3032 | pwr_move /= SCHED_POWER_SCALE; |
3032 | 3033 | ||
3033 | /* Move if we gain throughput */ | 3034 | /* Move if we gain throughput */ |
3034 | if (pwr_move > pwr_now) | 3035 | if (pwr_move > pwr_now) |
@@ -3070,7 +3071,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, | |||
3070 | load_above_capacity = (sds->busiest_nr_running - | 3071 | load_above_capacity = (sds->busiest_nr_running - |
3071 | sds->busiest_group_capacity); | 3072 | sds->busiest_group_capacity); |
3072 | 3073 | ||
3073 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_LOAD_SCALE); | 3074 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); |
3074 | 3075 | ||
3075 | load_above_capacity /= sds->busiest->cpu_power; | 3076 | load_above_capacity /= sds->busiest->cpu_power; |
3076 | } | 3077 | } |
@@ -3090,7 +3091,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, | |||
3090 | /* How much load to actually move to equalise the imbalance */ | 3091 | /* How much load to actually move to equalise the imbalance */ |
3091 | *imbalance = min(max_pull * sds->busiest->cpu_power, | 3092 | *imbalance = min(max_pull * sds->busiest->cpu_power, |
3092 | (sds->avg_load - sds->this_load) * sds->this->cpu_power) | 3093 | (sds->avg_load - sds->this_load) * sds->this->cpu_power) |
3093 | / SCHED_LOAD_SCALE; | 3094 | / SCHED_POWER_SCALE; |
3094 | 3095 | ||
3095 | /* | 3096 | /* |
3096 | * if *imbalance is less than the average load per runnable task | 3097 | * if *imbalance is less than the average load per runnable task |
@@ -3159,7 +3160,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
3159 | if (!sds.busiest || sds.busiest_nr_running == 0) | 3160 | if (!sds.busiest || sds.busiest_nr_running == 0) |
3160 | goto out_balanced; | 3161 | goto out_balanced; |
3161 | 3162 | ||
3162 | sds.avg_load = (SCHED_LOAD_SCALE * sds.total_load) / sds.total_pwr; | 3163 | sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr; |
3163 | 3164 | ||
3164 | /* | 3165 | /* |
3165 | * If the busiest group is imbalanced the below checks don't | 3166 | * If the busiest group is imbalanced the below checks don't |
@@ -3238,7 +3239,8 @@ find_busiest_queue(struct sched_domain *sd, struct sched_group *group, | |||
3238 | 3239 | ||
3239 | for_each_cpu(i, sched_group_cpus(group)) { | 3240 | for_each_cpu(i, sched_group_cpus(group)) { |
3240 | unsigned long power = power_of(i); | 3241 | unsigned long power = power_of(i); |
3241 | unsigned long capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE); | 3242 | unsigned long capacity = DIV_ROUND_CLOSEST(power, |
3243 | SCHED_POWER_SCALE); | ||
3242 | unsigned long wl; | 3244 | unsigned long wl; |
3243 | 3245 | ||
3244 | if (!capacity) | 3246 | if (!capacity) |
@@ -3263,7 +3265,7 @@ find_busiest_queue(struct sched_domain *sd, struct sched_group *group, | |||
3263 | * the load can be moved away from the cpu that is potentially | 3265 | * the load can be moved away from the cpu that is potentially |
3264 | * running at a lower capacity. | 3266 | * running at a lower capacity. |
3265 | */ | 3267 | */ |
3266 | wl = (wl * SCHED_LOAD_SCALE) / power; | 3268 | wl = (wl * SCHED_POWER_SCALE) / power; |
3267 | 3269 | ||
3268 | if (wl > max_load) { | 3270 | if (wl > max_load) { |
3269 | max_load = wl; | 3271 | max_load = wl; |