sched: set loop_max after rq lock is taken
RFC 1/3 sched: set loop_max after rq lock is taken
From: Uladzislau 2 Rezki <[email protected]>
While doing a load balance there is a race in setting loop_max variable since nr_running can be changed causing incorect iteration loops.
As a result we may skip some candidates or check the same tasks again.
--- kernel/sched/fair.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/sched/fair.c +6 -1
@@ -7744,12 +7744,17 @@ static int load_balance(int this_cpu, struct rq *this_rq,* correctly treated as an imbalance. */ env.flags |=LBF_ALL_PINNED ; - env.loop_max =min (sysctl_sched_nr_migrate, busiest->nr_running); more_balance:raw_spin_lock_irqsave (&busiest->lock, flags);/* +* Set loop_max when rq's lock is taken to prevent a race. +*/ + env.loop_max =min (sysctl_sched_nr_migrate, + busiest->nr_running); + +/* * cur_ld_moved - load moved in current iteration * ld_moved - cumulative load moved across iterations */
Signature · 1 line
2.1.4
RFC 2/3 sched: set number of iterations to h_nr_running
From: Uladzislau 2 Rezki <[email protected]>
It is possible that busiest run queue has multiple RT tasks, whereas no CFS tasks, that is why it is reasonable to use h_nr_running instead, because a load balance only applies for CFS related tasks.
--- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/fair.c +1 -1
@@ -7752,7 +7752,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,* Set loop_max when rq's lock is taken to prevent a race. */ env.loop_max =min (sysctl_sched_nr_migrate, - busiest->nr_running); + busiest->cfs.h_nr_running);/* * cur_ld_moved - load moved in current iteration
Signature · 1 line
2.1.4
RFC 3/3 sched: ignore task_h_load for CPU_NEWLY_IDLE
In reply to Uladzislau RezkiFrom: Uladzislau 2 Rezki <[email protected]>
A load balancer calculates imbalance factor for particular shed domain and tries to steal up the prescribed amount of weighted load. However, a small imbalance factor would sometimes prevent us from stealing any tasks at all. When a CPU is newly idle, it should steal first task which passes a migration criteria.
--- kernel/sched/fair.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/sched/fair.c +3 -2
@@ -6534,8 +6534,9 @@ static int detach_tasks(struct lb_env *env)if (sched_feat (LB_MIN ) && load <16 && !env->sd->nr_balance_failed) goto next; -if ((load /2 ) > env->imbalance) - goto next; +if (env->idle !=CPU_NEWLY_IDLE ) +if ((load /2 ) > env->imbalance) + goto next;detach_task (p, env);list_add (&p->se.group_node, &env->tasks);
Signature · 1 line
2.1.4