Hi Leo,
On 23 June 2016 at 15:43, Leo Yan leo.yan@linaro.org wrote:
When calculate imbalance between two clusters, then need calculate average load between clusters so finally can easily get to know how much load should be migrated.
Let's see the example for there have two clusters, cluster_A load_avg = 600 and cluster_B load_avg = 200; so the average load cross these two clusters = 400 if both of them have same capacity value.
If cluster_A capacity is 512 and cluster_B capacity is 1024, then that means cluster_B need migrate below load so cluster_A and cluster_B can get same load level:
It's not clear for me which issue you try to fix. AFAICT, caculate_imbalance returns the right value (333) for your use case
cluster A average load will become = (600-333) / 512 = 0.52 cluster B average load will become = (200+333) / 1024 = 0.52 system average load is (600+200)/(512+1024) = 0.52
avg_load(A) - X = avg_load(B) + X * capacity(A) / capacity(B)
avg_load(A) * capacity(B) - avg_load(B) * capacity(B)
X = ---------------------------------------------------------- capacity(A) + capacity(B)
The middle level load is:
avg_load(A) * capacity(A) + avg_load(B) * capacity(B)
capacity(A) + capacity(B)
So finally total_load = avg_load(A) * capacity(A) + avg_load(B) * capacity(B).
Signed-off-by: Leo Yan leo.yan@linaro.org
kernel/sched/fair.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 353520d..16e1fe2b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7441,7 +7441,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
next_group: /* Now, start updating sd_lb_stats */
sds->total_load += sgs->group_load;
sds->total_load += sgs->group_load * sgs->group_capacity /
SCHED_CAPACITY_SCALE / sgs->group_weight;
What are you trying to compute here ? and why have you use sgs->group_weight
We already have sds.avg_load = (SCHED_CAPACITY_SCALE * sds.total_load) / sds.total_capacity; in the find_busiest_group function.
so the computation above seems redundant
sds->total_capacity += sgs->group_capacity; sg = sg->next;
@@ -7526,7 +7527,7 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) { unsigned long tmp, capa_now = 0, capa_move = 0; unsigned int imbn = 2;
unsigned long scaled_busy_load_per_task;
unsigned long scaled_busy_load_per_task, scaled_local_load_per_task; struct sg_lb_stats *local, *busiest; local = &sds->local_stat;
@@ -7541,8 +7542,12 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) (busiest->load_per_task * SCHED_CAPACITY_SCALE) / busiest->group_capacity;
scaled_local_load_per_task =
(busiest->load_per_task * SCHED_CAPACITY_SCALE) /
local->group_capacity;
if (busiest->avg_load + scaled_busy_load_per_task >=
local->avg_load + (scaled_busy_load_per_task * imbn)) {
local->avg_load + (scaled_local_load_per_task * imbn)) { env->imbalance = busiest->load_per_task; return; }
-- 1.9.1