Skip to content

Commit 2c503ec

Browse files
HuangShijie20241Naim
authored andcommitted
sched/fair: do not scan twice in detach_tasks()
detach_tasks() uses struct lb_env.loop_max as an env.src_rq->cfs_tasks iteration count limit. It is however set without the source RQ lock held. This means that env.loop_max and the actual length of env.src_rq->cfs_tasks as observed within detach_tasks() can differ. This can cause some tasks to be unnecessarily iterated over more than once, for instance: env.loop_max := 4 detach_tasks() // Here env.src->cfs_tasks only contains two tasks which can't be // migrated anywhere, so they're put back in the list each time. env.src->cfs_tasks := [p1, p0] // The iteration goes: p0; cfs_tasks := [p0, p1] p1; cfs_tasks := [p1, p0] p0; cfs_tasks := [p0, p1] p1; cfs_tasks := [p1, p0] // IOW we iterate over each task twice In the Specjbb test, the similar issues can be caught many times. (Over 330,000 times in a 30-minites Specjbb test) This patch sets env.loop_max only once RQ lock is taken, and uses busiest->cfs.h_nr_queued for setting the env.loop_max. After this patch, I cannot catch any above issue in the Specjbb test. Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Reviewed-by: Valentin Schneider <vschneid@redhat.com>
1 parent c80ed4e commit 2c503ec

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

kernel/sched/fair.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11932,12 +11932,15 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq,
1193211932
* still unbalanced. ld_moved simply stays zero, so it is
1193311933
* correctly treated as an imbalance.
1193411934
*/
11935-
env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running);
11936-
1193711935
more_balance:
1193811936
rq_lock_irqsave(busiest, &rf);
1193911937
update_rq_clock(busiest);
1194011938

11939+
if (!env.loop_max)
11940+
env.loop_max = min(sysctl_sched_nr_migrate, busiest->cfs.h_nr_queued);
11941+
else
11942+
env.loop_max = min(env.loop_max, busiest->cfs.h_nr_queued);
11943+
1194111944
/*
1194211945
* cur_ld_moved - load moved in current iteration
1194311946
* ld_moved - cumulative load moved across iterations

0 commit comments

Comments
 (0)