Commit e9265e74 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Thomas Gleixner

sched: try to deal with low capacity

When the capacity drops low, we want to migrate load away. Allow the
load-balancer to remove all tasks when we hit rock bottom.

[ dino: backport to 31-rt ]
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Darren Hart <dvhltc@us.ibm.com>
Cc: John Kacur <jkacur@redhat.com>
[ego@in.ibm.com: fix to update_sd_power_savings_stats]
Signed-off-by: default avatarDinakar Guniguntala <dino@in.ibm.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 82e5a1bb
...@@ -3749,7 +3749,7 @@ static inline void update_sd_power_savings_stats(struct sched_group *group, ...@@ -3749,7 +3749,7 @@ static inline void update_sd_power_savings_stats(struct sched_group *group,
* capacity but still has some space to pick up some load * capacity but still has some space to pick up some load
* from other group and save more power * from other group and save more power
*/ */
if (sgs->sum_nr_running > sgs->group_capacity - 1) if (sgs->sum_nr_running + 1 > sgs->group_capacity)
return; return;
if (sgs->sum_nr_running > sds->leader_nr_running || if (sgs->sum_nr_running > sds->leader_nr_running ||
...@@ -3989,8 +3989,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, ...@@ -3989,8 +3989,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
if ((max_cpu_load - min_cpu_load) > 2*avg_load_per_task) if ((max_cpu_load - min_cpu_load) > 2*avg_load_per_task)
sgs->group_imb = 1; sgs->group_imb = 1;
sgs->group_capacity = group->__cpu_power / SCHED_LOAD_SCALE; sgs->group_capacity =
DIV_ROUND_CLOSEST(group->__cpu_power, SCHED_LOAD_SCALE);
} }
/** /**
...@@ -4040,7 +4040,7 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu, ...@@ -4040,7 +4040,7 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
* and move all the excess tasks away. * and move all the excess tasks away.
*/ */
if (prefer_sibling) if (prefer_sibling)
sgs.group_capacity = 1; sgs.group_capacity = min(sgs.group_capacity, 1UL);
if (local_group) { if (local_group) {
sds->this_load = sgs.avg_load; sds->this_load = sgs.avg_load;
...@@ -4272,6 +4272,26 @@ ret: ...@@ -4272,6 +4272,26 @@ ret:
return NULL; return NULL;
} }
static struct sched_group *group_of(int cpu)
{
struct sched_domain *sd = rcu_dereference(cpu_rq(cpu)->sd);
if (!sd)
return NULL;
return sd->groups;
}
static unsigned long power_of(int cpu)
{
struct sched_group *group = group_of(cpu);
if (!group)
return SCHED_LOAD_SCALE;
return group->__cpu_power;
}
/* /*
* find_busiest_queue - find the busiest runqueue among the cpus in group. * find_busiest_queue - find the busiest runqueue among the cpus in group.
*/ */
...@@ -4284,15 +4304,18 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle, ...@@ -4284,15 +4304,18 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
int i; int i;
for_each_cpu(i, sched_group_cpus(group)) { for_each_cpu(i, sched_group_cpus(group)) {
unsigned long power = power_of(i);
unsigned long capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
unsigned long wl; unsigned long wl;
if (!cpumask_test_cpu(i, cpus)) if (!cpumask_test_cpu(i, cpus))
continue; continue;
rq = cpu_rq(i); rq = cpu_rq(i);
wl = weighted_cpuload(i); wl = weighted_cpuload(i) * SCHED_LOAD_SCALE;
wl /= power;
if (rq->nr_running == 1 && wl > imbalance) if (capacity && rq->nr_running == 1 && wl > imbalance)
continue; continue;
if (wl > max_load) { if (wl > max_load) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment