Hi Leo,
On 05-Mar 15:57, Viresh Kumar wrote:
From: Leo Yan leo.yan@linaro.org
The homescreen test-case shows unwanted disturbance on the big CPUs on the Hikey620 platform with Android 4.9. There are multiple reasons for that though.
By default boost and prefer_idle are enabled for both top-app and foreground tasks and find_best_target() always (intentionally) prefers the big CPUs if prefer_idle is enabled. And some of the foreground tasks (like: DispSync, PowerManagerSer and PhotonicModulat) for the homescreen test-case get placed on the big CPUs eventually because of that.
Even if prefer_idle is disabled for such foreground tasks, they don't end up on the little CPUs. The reason being that find_best_target() still prefers big CPUs if the task is boosted, though some of the
^^^^^^^
Would say we don't prefer, but "just" start from big CPUs...
comments in find_best_target() routine say the exact opposite of that.
I guess you are referring to this comment:
* Case B) Non latency sensitive tasks on IDLE CPUs. * * Find an optimal backup IDLE CPU for non latency * sensitive tasks. * * Looking for: * - minimizing the capacity_orig, * i.e. preferring LITTLE CPUs * - favoring shallowest idle states * i.e. avoid to wakeup deep-idle CPUs * * The following code path is used by non latency * sensitive tasks if IDLE CPUs are available. If at * least one of such CPUs are available it sets the * best_idle_cpu to the most suitable idle CPU to be * selected. * * If idle CPUs are available, favour these CPUs to * improve performances by spreading tasks. * Indeed, the energy_diff() computed by the caller * will take care to ensure the minimization of energy * consumptions without affecting performance.
This comment does not assume any visiting ordering... which is intentional since we wanna, potentially, go thought all the CPUs and find the best target by just doing min/max aggregations... more on that later.
It eventually depends on the order in which CPUs are processed, which is from big to little for boosted tasks.
Order matter yes, but in case B we still do a minimization of the capacity_orig... thus eventually preferring LITTLE over big IDLE CPUs.
The only exception to this is when "sysctl_sched_cstate_aware" is set... which could end up in selection a big CPU over a LITTLE just because it's in a shallowest IDLE state.
Being B the case of non latency sensitive tasks, I'm wondering how much sense still have that condition... since it's definitively affecting our min/max aggregation in a potential bad way...
Do you have this sysctl set in your use-cases?
This patch updates the find_best_target() routine to select low capacity idle-CPU if the task is boosted but doesn't have prefer_idle enabled. This would be the same for non-boosted tasks as well.
Without cstate awareness, I would say we always end up preferring a LITTLE over an big CPU... provided they are both IDLE. Isn't it?
Signed-off-by: Leo Yan leo.yan@linaro.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org
kernel/sched/fair.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e45047bdd245..4534d8620989 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6998,8 +6998,11 @@ static inline int find_best_target(struct task_struct *p, int *backup_cpu, int idle_idx = idle_get_state_idx(cpu_rq(i));
/* Select idle CPU with lower cap_orig */
if (capacity_orig > best_idle_min_cap_orig)
if (capacity_orig < best_idle_min_cap_orig)
goto found_best_idle_cpu;
else if (capacity_orig > best_idle_min_cap_orig) continue;
/* Favor CPUs that won't end up running at a * high OPP. */
@@ -7017,6 +7020,7 @@ static inline int find_best_target(struct task_struct *p, int *backup_cpu, best_idle_cstate <= idle_idx) continue;
+found_best_idle_cpu: /* Keep track of best idle CPU */ best_idle_min_cap_orig = capacity_orig; target_idle_max_spare_cap = capacity_orig - -- 2.15.0.194.g9af6a3dea062
-- #include <best/regards.h>
Patrick Bellasi