Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-26 Thread Peter Zijlstra
On Sat, Aug 24, 2013 at 03:09:38AM -0700, Paul Turner wrote:
> On Mon, Aug 19, 2013 at 9:01 AM, Peter Zijlstra  wrote:
> > +   struct sg_lb_stats *this, *busiest;
> 
> "this" is a little confusing to read; mainly because elsewhere we've
> tied this to "this cpu" whereas the local sched group is arger.  (Not
> to mention the obvious OOP-land overloading of "this->".)
> 
> Perhaps %s/this/local/ for sg_lb_stat references?  Including this_stat
> -> local_stat on sd_lb_stats?

fair enough, I'll edit the thing to be local.

> > @@ -4952,15 +4950,16 @@ find_busiest_group(struct lb_env *env)
> >  * there is no imbalance between this and busiest group
> >  * wrt to idle cpu's, it is balanced.
> >  */
> > -   if ((sds.this_idle_cpus <= sds.busiest_idle_cpus + 1) &&
> > -   sds.busiest_nr_running <= sds.busiest_group_weight)
> > +   if ((this->idle_cpus <= busiest->idle_cpus + 1) &&
> > +   busiest->sum_nr_running <= busiest->group_weight)
> 
> While we're improving readability:  idle_cpus < busiest->idle_cpus ?

Right, took that.

> This check has always been a little oddly asymmetric in that:
>   group_weight - sum_nr_running <= idle_cpus
> 
> This allows the case where our group has pulled lots of work to one of
> its cpus, but not yet spread that out, but still keep trying to
> balance because idle_cpus is high.
> 
> This is more food for thought since this patch is not changing functionality.

Right, I saw the same and made a note to look at it later. I suppose
later never happens though :/ 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-26 Thread Lei Wen
On Mon, Aug 26, 2013 at 12:36 PM, Paul Turner  wrote:
> On Sun, Aug 25, 2013 at 7:56 PM, Lei Wen  wrote:
>> On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra  
>> wrote:
>>> From: Joonsoo Kim 
>>>
>>> There is no reason to maintain separate variables for this_group
>>> and busiest_group in sd_lb_stat, except saving some space.
>>> But this structure is always allocated in stack, so this saving
>>> isn't really benificial [peterz: reducing stack space is good; in this
>>> case readability increases enough that I think its still beneficial]
>>>
>>> This patch unify these variables, so IMO, readability may be improved.
>>>
>>> Signed-off-by: Joonsoo Kim 
>>> [peterz: lots of style edits, a few fixes and a rename]
>>> Signed-off-by: Peter Zijlstra 
>>> Link: 
>>> http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
>>> ---
>>>  kernel/sched/fair.c |  225 
>>> +---
>>>  1 file changed, 112 insertions(+), 113 deletions(-)
>>>
>>> --- a/kernel/sched/fair.c
>>> +++ b/kernel/sched/fair.c
>>> @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct
>>>
>> [snip]...
>>> -   env->imbalance = DIV_ROUND_CLOSEST(
>>> -   sds->max_load * sds->busiest->sgp->power, 
>>> SCHED_POWER_SCALE);
>>> +   env->imbalance = DIV_ROUND_CLOSEST(sds->busiest_stat.avg_load *
>>> +   sds->busiest->sgp->power, 
>>> SCHED_POWER_SCALE);
>>>
>>
>> I am wondering whether we could change this line as below is more 
>> appropriate,
>> since it would avoid the division here:
>>env->imbalance = (sds->busiest_stat.avg_load * 
>> sds->busiest->sgp->power)
>>   >> SCHED_POWER_SHIFT;
>>
>> I am not sure whether compiler would be smarter enough to covert into
 operation,
>> if it see SCHED_POWER_SCALE is 1024 here.
>
> This would change the rounding.  Fortunately, gcc is smart enough to
> handle this.

Indeed, I check the assembly code, and it is really smart to do the changes.

Thanks,
Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-26 Thread Lei Wen
On Mon, Aug 26, 2013 at 12:36 PM, Paul Turner p...@google.com wrote:
 On Sun, Aug 25, 2013 at 7:56 PM, Lei Wen adrian.w...@gmail.com wrote:
 On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra pet...@infradead.org 
 wrote:
 From: Joonsoo Kim iamjoonsoo@lge.com

 There is no reason to maintain separate variables for this_group
 and busiest_group in sd_lb_stat, except saving some space.
 But this structure is always allocated in stack, so this saving
 isn't really benificial [peterz: reducing stack space is good; in this
 case readability increases enough that I think its still beneficial]

 This patch unify these variables, so IMO, readability may be improved.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com
 [peterz: lots of style edits, a few fixes and a rename]
 Signed-off-by: Peter Zijlstra pet...@infradead.org
 Link: 
 http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
 ---
  kernel/sched/fair.c |  225 
 +---
  1 file changed, 112 insertions(+), 113 deletions(-)

 --- a/kernel/sched/fair.c
 +++ b/kernel/sched/fair.c
 @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct

 [snip]...
 -   env-imbalance = DIV_ROUND_CLOSEST(
 -   sds-max_load * sds-busiest-sgp-power, 
 SCHED_POWER_SCALE);
 +   env-imbalance = DIV_ROUND_CLOSEST(sds-busiest_stat.avg_load *
 +   sds-busiest-sgp-power, 
 SCHED_POWER_SCALE);


 I am wondering whether we could change this line as below is more 
 appropriate,
 since it would avoid the division here:
env-imbalance = (sds-busiest_stat.avg_load * 
 sds-busiest-sgp-power)
SCHED_POWER_SHIFT;

 I am not sure whether compiler would be smarter enough to covert into
 operation,
 if it see SCHED_POWER_SCALE is 1024 here.

 This would change the rounding.  Fortunately, gcc is smart enough to
 handle this.

Indeed, I check the assembly code, and it is really smart to do the changes.

Thanks,
Lei
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-26 Thread Peter Zijlstra
On Sat, Aug 24, 2013 at 03:09:38AM -0700, Paul Turner wrote:
 On Mon, Aug 19, 2013 at 9:01 AM, Peter Zijlstra pet...@infradead.org wrote:
  +   struct sg_lb_stats *this, *busiest;
 
 this is a little confusing to read; mainly because elsewhere we've
 tied this to this cpu whereas the local sched group is arger.  (Not
 to mention the obvious OOP-land overloading of this-.)
 
 Perhaps %s/this/local/ for sg_lb_stat references?  Including this_stat
 - local_stat on sd_lb_stats?

fair enough, I'll edit the thing to be local.

  @@ -4952,15 +4950,16 @@ find_busiest_group(struct lb_env *env)
   * there is no imbalance between this and busiest group
   * wrt to idle cpu's, it is balanced.
   */
  -   if ((sds.this_idle_cpus = sds.busiest_idle_cpus + 1) 
  -   sds.busiest_nr_running = sds.busiest_group_weight)
  +   if ((this-idle_cpus = busiest-idle_cpus + 1) 
  +   busiest-sum_nr_running = busiest-group_weight)
 
 While we're improving readability:  idle_cpus  busiest-idle_cpus ?

Right, took that.

 This check has always been a little oddly asymmetric in that:
   group_weight - sum_nr_running = idle_cpus
 
 This allows the case where our group has pulled lots of work to one of
 its cpus, but not yet spread that out, but still keep trying to
 balance because idle_cpus is high.
 
 This is more food for thought since this patch is not changing functionality.

Right, I saw the same and made a note to look at it later. I suppose
later never happens though :/ 


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-25 Thread Paul Turner
On Sun, Aug 25, 2013 at 7:56 PM, Lei Wen  wrote:
> On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra  wrote:
>> From: Joonsoo Kim 
>>
>> There is no reason to maintain separate variables for this_group
>> and busiest_group in sd_lb_stat, except saving some space.
>> But this structure is always allocated in stack, so this saving
>> isn't really benificial [peterz: reducing stack space is good; in this
>> case readability increases enough that I think its still beneficial]
>>
>> This patch unify these variables, so IMO, readability may be improved.
>>
>> Signed-off-by: Joonsoo Kim 
>> [peterz: lots of style edits, a few fixes and a rename]
>> Signed-off-by: Peter Zijlstra 
>> Link: 
>> http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
>> ---
>>  kernel/sched/fair.c |  225 
>> +---
>>  1 file changed, 112 insertions(+), 113 deletions(-)
>>
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct
>>
> [snip]...
>> -   env->imbalance = DIV_ROUND_CLOSEST(
>> -   sds->max_load * sds->busiest->sgp->power, SCHED_POWER_SCALE);
>> +   env->imbalance = DIV_ROUND_CLOSEST(sds->busiest_stat.avg_load *
>> +   sds->busiest->sgp->power, SCHED_POWER_SCALE);
>>
>
> I am wondering whether we could change this line as below is more appropriate,
> since it would avoid the division here:
>env->imbalance = (sds->busiest_stat.avg_load * 
> sds->busiest->sgp->power)
>   >> SCHED_POWER_SHIFT;
>
> I am not sure whether compiler would be smarter enough to covert into
>>> operation,
> if it see SCHED_POWER_SCALE is 1024 here.

This would change the rounding.  Fortunately, gcc is smart enough to
handle this.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-25 Thread Lei Wen
On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra  wrote:
> From: Joonsoo Kim 
>
> There is no reason to maintain separate variables for this_group
> and busiest_group in sd_lb_stat, except saving some space.
> But this structure is always allocated in stack, so this saving
> isn't really benificial [peterz: reducing stack space is good; in this
> case readability increases enough that I think its still beneficial]
>
> This patch unify these variables, so IMO, readability may be improved.
>
> Signed-off-by: Joonsoo Kim 
> [peterz: lots of style edits, a few fixes and a rename]
> Signed-off-by: Peter Zijlstra 
> Link: 
> http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
> ---
>  kernel/sched/fair.c |  225 
> +---
>  1 file changed, 112 insertions(+), 113 deletions(-)
>
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct
>
[snip]...
> -   env->imbalance = DIV_ROUND_CLOSEST(
> -   sds->max_load * sds->busiest->sgp->power, SCHED_POWER_SCALE);
> +   env->imbalance = DIV_ROUND_CLOSEST(sds->busiest_stat.avg_load *
> +   sds->busiest->sgp->power, SCHED_POWER_SCALE);
>

I am wondering whether we could change this line as below is more appropriate,
since it would avoid the division here:
   env->imbalance = (sds->busiest_stat.avg_load * sds->busiest->sgp->power)
  >> SCHED_POWER_SHIFT;

I am not sure whether compiler would be smarter enough to covert into
>> operation,
if it see SCHED_POWER_SCALE is 1024 here.

Thanks,
Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-25 Thread Lei Wen
On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra pet...@infradead.org wrote:
 From: Joonsoo Kim iamjoonsoo@lge.com

 There is no reason to maintain separate variables for this_group
 and busiest_group in sd_lb_stat, except saving some space.
 But this structure is always allocated in stack, so this saving
 isn't really benificial [peterz: reducing stack space is good; in this
 case readability increases enough that I think its still beneficial]

 This patch unify these variables, so IMO, readability may be improved.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com
 [peterz: lots of style edits, a few fixes and a rename]
 Signed-off-by: Peter Zijlstra pet...@infradead.org
 Link: 
 http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
 ---
  kernel/sched/fair.c |  225 
 +---
  1 file changed, 112 insertions(+), 113 deletions(-)

 --- a/kernel/sched/fair.c
 +++ b/kernel/sched/fair.c
 @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct

[snip]...
 -   env-imbalance = DIV_ROUND_CLOSEST(
 -   sds-max_load * sds-busiest-sgp-power, SCHED_POWER_SCALE);
 +   env-imbalance = DIV_ROUND_CLOSEST(sds-busiest_stat.avg_load *
 +   sds-busiest-sgp-power, SCHED_POWER_SCALE);


I am wondering whether we could change this line as below is more appropriate,
since it would avoid the division here:
   env-imbalance = (sds-busiest_stat.avg_load * sds-busiest-sgp-power)
   SCHED_POWER_SHIFT;

I am not sure whether compiler would be smarter enough to covert into
 operation,
if it see SCHED_POWER_SCALE is 1024 here.

Thanks,
Lei
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-25 Thread Paul Turner
On Sun, Aug 25, 2013 at 7:56 PM, Lei Wen adrian.w...@gmail.com wrote:
 On Tue, Aug 20, 2013 at 12:01 AM, Peter Zijlstra pet...@infradead.org wrote:
 From: Joonsoo Kim iamjoonsoo@lge.com

 There is no reason to maintain separate variables for this_group
 and busiest_group in sd_lb_stat, except saving some space.
 But this structure is always allocated in stack, so this saving
 isn't really benificial [peterz: reducing stack space is good; in this
 case readability increases enough that I think its still beneficial]

 This patch unify these variables, so IMO, readability may be improved.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com
 [peterz: lots of style edits, a few fixes and a rename]
 Signed-off-by: Peter Zijlstra pet...@infradead.org
 Link: 
 http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
 ---
  kernel/sched/fair.c |  225 
 +---
  1 file changed, 112 insertions(+), 113 deletions(-)

 --- a/kernel/sched/fair.c
 +++ b/kernel/sched/fair.c
 @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct

 [snip]...
 -   env-imbalance = DIV_ROUND_CLOSEST(
 -   sds-max_load * sds-busiest-sgp-power, SCHED_POWER_SCALE);
 +   env-imbalance = DIV_ROUND_CLOSEST(sds-busiest_stat.avg_load *
 +   sds-busiest-sgp-power, SCHED_POWER_SCALE);


 I am wondering whether we could change this line as below is more appropriate,
 since it would avoid the division here:
env-imbalance = (sds-busiest_stat.avg_load * 
 sds-busiest-sgp-power)
SCHED_POWER_SHIFT;

 I am not sure whether compiler would be smarter enough to covert into
 operation,
 if it see SCHED_POWER_SCALE is 1024 here.

This would change the rounding.  Fortunately, gcc is smart enough to
handle this.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-24 Thread Paul Turner
On Mon, Aug 19, 2013 at 9:01 AM, Peter Zijlstra  wrote:
> From: Joonsoo Kim 
>
> There is no reason to maintain separate variables for this_group
> and busiest_group in sd_lb_stat, except saving some space.
> But this structure is always allocated in stack, so this saving
> isn't really benificial [peterz: reducing stack space is good; in this
> case readability increases enough that I think its still beneficial]
>
> This patch unify these variables, so IMO, readability may be improved.
>
> Signed-off-by: Joonsoo Kim 
> [peterz: lots of style edits, a few fixes and a rename]
> Signed-off-by: Peter Zijlstra 
> Link: 
> http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
> ---
>  kernel/sched/fair.c |  225 
> +---
>  1 file changed, 112 insertions(+), 113 deletions(-)
>
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct
>
>  /** Helpers for find_busiest_group /
>  /*
> - * sd_lb_stats - Structure to store the statistics of a sched_domain
> - * during load balancing.
> - */
> -struct sd_lb_stats {
> -   struct sched_group *busiest; /* Busiest group in this sd */
> -   struct sched_group *this;  /* Local group in this sd */
> -   unsigned long total_load;  /* Total load of all groups in sd */
> -   unsigned long total_pwr;   /*   Total power of all groups in sd */
> -   unsigned long avg_load;/* Average load across all groups in sd */
> -
> -   /** Statistics of this group */
> -   unsigned long this_load;
> -   unsigned long this_load_per_task;
> -   unsigned long this_nr_running;
> -   unsigned long this_has_capacity;
> -   unsigned int  this_idle_cpus;
> -
> -   /* Statistics of the busiest group */
> -   unsigned int  busiest_idle_cpus;
> -   unsigned long max_load;
> -   unsigned long busiest_load_per_task;
> -   unsigned long busiest_nr_running;
> -   unsigned long busiest_group_capacity;
> -   unsigned long busiest_has_capacity;
> -   unsigned int  busiest_group_weight;
> -
> -   int group_imb; /* Is there imbalance in this sd */
> -};
> -
> -/*
>   * sg_lb_stats - stats of a sched_group required for load_balancing
>   */
>  struct sg_lb_stats {
> @@ -4314,6 +4284,7 @@ struct sg_lb_stats {
> unsigned long group_load; /* Total load over the CPUs of the group */
> unsigned long sum_nr_running; /* Nr tasks running in the group */
> unsigned long sum_weighted_load; /* Weighted load of group's tasks */
> +   unsigned long load_per_task;
> unsigned long group_capacity;
> unsigned long idle_cpus;
> unsigned long group_weight;
> @@ -4321,6 +4292,21 @@ struct sg_lb_stats {
> int group_has_capacity; /* Is there extra capacity in the group? */
>  };
>
> +/*
> + * sd_lb_stats - Structure to store the statistics of a sched_domain
> + *  during load balancing.
> + */
> +struct sd_lb_stats {
> +   struct sched_group *busiest;/* Busiest group in this sd */
> +   struct sched_group *this;   /* Local group in this sd */
> +   unsigned long total_load;   /* Total load of all groups in sd */
> +   unsigned long total_pwr;/* Total power of all groups in sd */
> +   unsigned long avg_load; /* Average load across all groups in sd */
> +
> +   struct sg_lb_stats this_stat;   /* Statistics of this group */
> +   struct sg_lb_stats busiest_stat;/* Statistics of the busiest group */
> +};
> +
>  /**
>   * get_sd_load_idx - Obtain the load index for a given sched domain.
>   * @sd: The sched_domain whose load_idx is to be obtained.
> @@ -4533,10 +4519,11 @@ static inline void update_sg_lb_stats(st
> nr_running = rq->nr_running;
>
> /* Bias balancing toward cpus of our domain */
> -   if (local_group)
> +   if (local_group) {
> load = target_load(i, load_idx);
> -   else {
> +   } else {
> load = source_load(i, load_idx);
> +
> if (load > max_cpu_load)
> max_cpu_load = load;
> if (min_cpu_load > load)
> @@ -4578,10 +4565,12 @@ static inline void update_sg_lb_stats(st
> (max_nr_running - min_nr_running) > 1)
> sgs->group_imb = 1;
>
> -   sgs->group_capacity = DIV_ROUND_CLOSEST(group->sgp->power,
> -   SCHED_POWER_SCALE);
> +   sgs->group_capacity =
> +   DIV_ROUND_CLOSEST(group->sgp->power, SCHED_POWER_SCALE);
> +
> if (!sgs->group_capacity)
> sgs->group_capacity = fix_small_capacity(env->sd, group);
> +
> sgs->group_weight = group->group_weight;
>
> if (sgs->group_capacity > sgs->sum_nr_running)
> @@ -4606,7 

Re: [PATCH 03/10] sched: Clean-up struct sd_lb_stat

2013-08-24 Thread Paul Turner
On Mon, Aug 19, 2013 at 9:01 AM, Peter Zijlstra pet...@infradead.org wrote:
 From: Joonsoo Kim iamjoonsoo@lge.com

 There is no reason to maintain separate variables for this_group
 and busiest_group in sd_lb_stat, except saving some space.
 But this structure is always allocated in stack, so this saving
 isn't really benificial [peterz: reducing stack space is good; in this
 case readability increases enough that I think its still beneficial]

 This patch unify these variables, so IMO, readability may be improved.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com
 [peterz: lots of style edits, a few fixes and a rename]
 Signed-off-by: Peter Zijlstra pet...@infradead.org
 Link: 
 http://lkml.kernel.org/r/1375778203-31343-4-git-send-email-iamjoonsoo@lge.com
 ---
  kernel/sched/fair.c |  225 
 +---
  1 file changed, 112 insertions(+), 113 deletions(-)

 --- a/kernel/sched/fair.c
 +++ b/kernel/sched/fair.c
 @@ -4277,36 +4277,6 @@ static unsigned long task_h_load(struct

  /** Helpers for find_busiest_group /
  /*
 - * sd_lb_stats - Structure to store the statistics of a sched_domain
 - * during load balancing.
 - */
 -struct sd_lb_stats {
 -   struct sched_group *busiest; /* Busiest group in this sd */
 -   struct sched_group *this;  /* Local group in this sd */
 -   unsigned long total_load;  /* Total load of all groups in sd */
 -   unsigned long total_pwr;   /*   Total power of all groups in sd */
 -   unsigned long avg_load;/* Average load across all groups in sd */
 -
 -   /** Statistics of this group */
 -   unsigned long this_load;
 -   unsigned long this_load_per_task;
 -   unsigned long this_nr_running;
 -   unsigned long this_has_capacity;
 -   unsigned int  this_idle_cpus;
 -
 -   /* Statistics of the busiest group */
 -   unsigned int  busiest_idle_cpus;
 -   unsigned long max_load;
 -   unsigned long busiest_load_per_task;
 -   unsigned long busiest_nr_running;
 -   unsigned long busiest_group_capacity;
 -   unsigned long busiest_has_capacity;
 -   unsigned int  busiest_group_weight;
 -
 -   int group_imb; /* Is there imbalance in this sd */
 -};
 -
 -/*
   * sg_lb_stats - stats of a sched_group required for load_balancing
   */
  struct sg_lb_stats {
 @@ -4314,6 +4284,7 @@ struct sg_lb_stats {
 unsigned long group_load; /* Total load over the CPUs of the group */
 unsigned long sum_nr_running; /* Nr tasks running in the group */
 unsigned long sum_weighted_load; /* Weighted load of group's tasks */
 +   unsigned long load_per_task;
 unsigned long group_capacity;
 unsigned long idle_cpus;
 unsigned long group_weight;
 @@ -4321,6 +4292,21 @@ struct sg_lb_stats {
 int group_has_capacity; /* Is there extra capacity in the group? */
  };

 +/*
 + * sd_lb_stats - Structure to store the statistics of a sched_domain
 + *  during load balancing.
 + */
 +struct sd_lb_stats {
 +   struct sched_group *busiest;/* Busiest group in this sd */
 +   struct sched_group *this;   /* Local group in this sd */
 +   unsigned long total_load;   /* Total load of all groups in sd */
 +   unsigned long total_pwr;/* Total power of all groups in sd */
 +   unsigned long avg_load; /* Average load across all groups in sd */
 +
 +   struct sg_lb_stats this_stat;   /* Statistics of this group */
 +   struct sg_lb_stats busiest_stat;/* Statistics of the busiest group */
 +};
 +
  /**
   * get_sd_load_idx - Obtain the load index for a given sched domain.
   * @sd: The sched_domain whose load_idx is to be obtained.
 @@ -4533,10 +4519,11 @@ static inline void update_sg_lb_stats(st
 nr_running = rq-nr_running;

 /* Bias balancing toward cpus of our domain */
 -   if (local_group)
 +   if (local_group) {
 load = target_load(i, load_idx);
 -   else {
 +   } else {
 load = source_load(i, load_idx);
 +
 if (load  max_cpu_load)
 max_cpu_load = load;
 if (min_cpu_load  load)
 @@ -4578,10 +4565,12 @@ static inline void update_sg_lb_stats(st
 (max_nr_running - min_nr_running)  1)
 sgs-group_imb = 1;

 -   sgs-group_capacity = DIV_ROUND_CLOSEST(group-sgp-power,
 -   SCHED_POWER_SCALE);
 +   sgs-group_capacity =
 +   DIV_ROUND_CLOSEST(group-sgp-power, SCHED_POWER_SCALE);
 +
 if (!sgs-group_capacity)
 sgs-group_capacity = fix_small_capacity(env-sd, group);
 +
 sgs-group_weight = group-group_weight;

 if (sgs-group_capacity  sgs-sum_nr_running)
 @@ -4606,7 +4595,7 @@ static bool update_sd_pick_busiest(struc