On 01/23/2017 11:42 PM, Leo Yan wrote:
On Mon, Jan 23, 2017 at 06:48:54PM -0800, Joonwoo Park wrote:
On Thu, Dec 22, 2016 at 11:58:50PM +0800, Leo Yan wrote:
Current code select busiest rq mostly consider only from weighted load this point of view; so it's possible to select one CPU with most weighted load value but this load are contributes by some small load tasks, on the other hand there have one another CPU with misfit task but it may have no chance to migrate task to higher capacity CPU.
This patch is to add one more checking for selection busiest rq if find only one misfit task on the rq and it's possible to migrate task from lower capacity CPU to higher capacity CPU.
Signed-off-by: Leo Yan leo.yan@linaro.org
kernel/sched/fair.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ed9fbed..1cf0e37 100755 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7777,6 +7777,24 @@ static struct rq *find_busiest_queue(struct lb_env *env, continue;
/*
* After enable energy awared scheduling, it has higher
* priority to migrate misfit task rather than from most
* loaded CPU; E.g. one CPU with single misfit task and
* other CPUs with multiple lower load tasks, we should
* firstly make sure the misfit task can be migrated onto
* higher capacity CPU.
*/
if (energy_aware() &&
capacity_orig_of(i) < capacity_orig_of(env->dst_cpu) &&
Do you want to check capacity_of() as well as capacity_orig_of()?
Here using capacity_orig_of() to distinguish the the src CPU and dst CPU have different 'original' capacity.
If check capacity_of(), this gives chance to migrate the task to the CPU within the same cluster, e.g. the src CPU is LITTLE CPU and it has one rt thread and one misfit task, and dst CPU is LITTLE CPU and it has no rt thread. So finally 'capacity_of(src_cpu) < capacity_of(dst_cpu)' is valid and migrate misfit task to another LITTLE CPU. This is pointless for misfit task.
Sorry for being late.
I meant to have both capacity_orig_of() as well as capacity_of() thus to be :
if (energy_aware() && capacity_orig_of(i) < capacity_orig_of(env->dst_cpu) && capacity_of(i) < capacity_of(env->dst_cpu))
capacity_orig_of() will take care of unnecessary migrations between same cluster CPUs. However I think there are cases cluster CPU, dst_cpu has less capacity than little CPU, i. For example due to rt task on the big cluster CPU as like you mentioned above. Also if big cluster CPU's fmax got mitigated for reasons like thermal, the max capacity inversion could happen I believe.
I tried rt-app with below json, looks like it's indeed happening.
Thanks, Joonwoo
---8<--- { "tasks" : { "ThreadA_other" : { "run" : 1000000, "sleep" : 1000, "loop" : 1000, "cpus" : [0,1,2,3], "policy" : "SCHED_OTHER", }, "ThreadA" : { "run" : 1000000, "sleep" : 1000, "loop" : 1000, "cpus" : [4], }, "ThreadB" : { "run" : 1000000, "sleep" : 1000, "loop" : 1000, "cpus" : [5], }, "ThreadC" : { "run" : 1000000, "sleep" : 1000, "loop" : 1000, "cpus" : [6], }, "ThreadD" : { "run" : 1000000, "sleep" : 100, "loop" : 1000, "cpus" : [7], }, }, "global" : { "default_policy" : "SCHED_FIFO", "duration" : 5, "ftrace" : false, "gnuplot" : false, "logdir" : "/data/", "log_basename" : "rt-app", "lock_pages" : true, "frag" : 1, "calibration" : "CPU0", } } ---