sched/walt cfs: rt: find a packing cpu

Under low-util conditions, small tasks can be packed onto
a single dedicated cpu per cluster, the first cpu in the
cluster. This can improve performance by ensuring fewer
exits from wfi or deep-idle, and reduce power by keeping
more of the other cpus in wfi or deep-idle, for longer.

Add the functionality to perform choosing of the packing cpu
and incorporate this into the select_rq path for fair and rt
in walt hooks.

Change-Id: I02675ceb6dd2e5fb40f4b14308159cc1fdde245e
Signed-off-by: Stephen Dickey <quic_dickey@quicinc.com>
This commit is contained in:
Stephen Dickey 2022-04-06 14:45:39 -07:00 committed by Rishabh Bhatnagar
parent e7853f5841
commit 36c37e32ce
2 changed files with 34 additions and 1 deletions

View File

@ -219,6 +219,7 @@ enum fastpaths {
NONE = 0,
SYNC_WAKEUP,
PREV_CPU_FASTPATH,
CLUSTER_PACKING_FASTPATH,
};
static inline bool is_complex_sibling_idle(int cpu)
@ -251,6 +252,7 @@ static void walt_find_best_target(struct sched_domain *sd,
bool rtg_high_prio_task = task_rtg_high_prio(p);
cpumask_t visit_cpus;
struct walt_task_struct *wts = (struct walt_task_struct *) p->android_vendor_data1;
int packing_cpu;
struct walt_rq *prev_wrq = (struct walt_rq *) cpu_rq(prev_cpu)->android_vendor_data1;
struct walt_rq *start_wrq;
@ -272,6 +274,14 @@ static void walt_find_best_target(struct sched_domain *sd,
most_spare_wake_cap = LONG_MIN;
}
/* fast path for packing_cpu */
packing_cpu = walt_find_cluster_packing_cpu(start_cpu);
if (walt_choose_packing_cpu(packing_cpu, p)) {
fbt_env->fastpath = CLUSTER_PACKING_FASTPATH;
cpumask_set_cpu(packing_cpu, candidates);
goto out;
}
/* fast path for prev_cpu */
if (((prev_wrq->cluster->id == start_wrq->cluster->id) ||
asym_cap_siblings(prev_cpu, start_cpu)) &&
@ -842,6 +852,12 @@ int walt_find_energy_efficient_cpu(struct task_struct *p, int prev_cpu,
goto unlock;
first_cpu = cpumask_first(candidates);
if (fbt_env.fastpath == CLUSTER_PACKING_FASTPATH) {
best_energy_cpu = first_cpu;
goto unlock;
}
if (weight == 1) {
if (available_idle_cpu(first_cpu) || first_cpu == prev_cpu) {
best_energy_cpu = first_cpu;

View File

@ -234,6 +234,7 @@ static void walt_select_task_rq_rt(void *unused, struct task_struct *task, int c
bool sync = !!(wake_flags & WF_SYNC);
int ret, target = -1, this_cpu;
struct cpumask *lowest_mask;
int packing_cpu;
if (unlikely(walt_disabled))
return;
@ -288,6 +289,13 @@ static void walt_select_task_rq_rt(void *unused, struct task_struct *task, int c
ret = cpupri_find_fitness(&task_rq(task)->rd->cpupri, task,
lowest_mask, walt_rt_task_fits_capacity);
/* create a fastpath for finding a packing cpu */
packing_cpu = walt_find_cluster_packing_cpu(task_cpu(task));
if (walt_choose_packing_cpu(packing_cpu, task)) {
*new_cpu = packing_cpu;
goto unlock;
}
walt_rt_energy_aware_wake_cpu(task, lowest_mask, ret, &target);
/*
@ -310,7 +318,7 @@ static void walt_select_task_rq_rt(void *unused, struct task_struct *task, int c
if (target < nr_cpu_ids)
*new_cpu = target;
}
unlock:
rcu_read_unlock();
}
@ -319,6 +327,15 @@ static void walt_rt_find_lowest_rq(void *unused, struct task_struct *task,
struct cpumask *lowest_mask, int ret, int *best_cpu)
{
int packing_cpu;
/* create a fastpath for finding a packing cpu */
packing_cpu = walt_find_cluster_packing_cpu(task_cpu(task));
if (walt_choose_packing_cpu(packing_cpu, task)) {
*best_cpu = packing_cpu;
return;
}
walt_rt_energy_aware_wake_cpu(task, lowest_mask, ret, best_cpu);
/*