mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 11:11:26 +02:00
sched: walt: update newidle balancing
There is a case where when big cluster(Gold/Prime) is entering idle it fails to pull task from lower cluster if lower cluster is only having a single big task in it's runqueue. The reason for failure is, walt skips newidle balance for above condition if "idle_cpu" check fails for destination core and for newidle balance destination core is entering idle (not yet idle) thus "idle_cpu" returns false. Fix this by skipping "idle_cpu" check for new idle balancing. Change-Id: Id973bd8a67fbfcd9d47bec9a0894b697412f2c90 Signed-off-by: Ashay Jaiswal <quic_ashayj@quicinc.com> Signed-off-by: Sai Harshini Nimmala <quic_snimmala@quicinc.com>
This commit is contained in:
parent
ff2d763574
commit
48c24c7316
|
|
@ -426,7 +426,7 @@ static int find_first_idle_if_others_are_busy(const cpumask_t *src_mask)
|
|||
}
|
||||
|
||||
static int walt_lb_find_busiest_similar_cap_cpu(int dst_cpu, const cpumask_t *src_mask,
|
||||
int *has_misfit)
|
||||
int *has_misfit, bool is_newidle)
|
||||
{
|
||||
int i;
|
||||
int busiest_cpu = -1;
|
||||
|
|
@ -452,7 +452,7 @@ static int walt_lb_find_busiest_similar_cap_cpu(int dst_cpu, const cpumask_t *sr
|
|||
}
|
||||
|
||||
static int walt_lb_find_busiest_from_higher_cap_cpu(int dst_cpu, const cpumask_t *src_mask,
|
||||
int *has_misfit)
|
||||
int *has_misfit, bool is_newidle)
|
||||
{
|
||||
int i;
|
||||
int busiest_cpu = -1;
|
||||
|
|
@ -512,7 +512,7 @@ static int walt_lb_find_busiest_from_higher_cap_cpu(int dst_cpu, const cpumask_t
|
|||
}
|
||||
|
||||
static int walt_lb_find_busiest_from_lower_cap_cpu(int dst_cpu, const cpumask_t *src_mask,
|
||||
int *has_misfit)
|
||||
int *has_misfit, bool is_newidle)
|
||||
{
|
||||
int i;
|
||||
int busiest_cpu = -1;
|
||||
|
|
@ -521,6 +521,7 @@ static int walt_lb_find_busiest_from_lower_cap_cpu(int dst_cpu, const cpumask_t
|
|||
int total_cpus = 0;
|
||||
int busy_nr_big_tasks = 0;
|
||||
struct walt_rq *wrq;
|
||||
bool treat_dst_idle = is_newidle || available_idle_cpu(dst_cpu);
|
||||
|
||||
/*
|
||||
* A higher capacity CPU is looking at a lower capacity
|
||||
|
|
@ -552,7 +553,7 @@ static int walt_lb_find_busiest_from_lower_cap_cpu(int dst_cpu, const cpumask_t
|
|||
|
||||
/* active migration is allowed only to idle cpu */
|
||||
if (cpu_rq(i)->cfs.h_nr_running < 2 &&
|
||||
(!wrq->walt_stats.nr_big_tasks || !available_idle_cpu(dst_cpu)))
|
||||
(!wrq->walt_stats.nr_big_tasks || !treat_dst_idle))
|
||||
continue;
|
||||
|
||||
if (!walt_rotation_enabled && !cpu_overutilized(i) &&
|
||||
|
|
@ -579,7 +580,8 @@ static int walt_lb_find_busiest_from_lower_cap_cpu(int dst_cpu, const cpumask_t
|
|||
return busiest_cpu;
|
||||
}
|
||||
|
||||
static int walt_lb_find_busiest_cpu(int dst_cpu, const cpumask_t *src_mask, int *has_misfit)
|
||||
static int walt_lb_find_busiest_cpu(int dst_cpu, const cpumask_t *src_mask, int *has_misfit,
|
||||
bool is_newidle)
|
||||
{
|
||||
int fsrc_cpu = cpumask_first(src_mask);
|
||||
int busiest_cpu;
|
||||
|
|
@ -588,13 +590,13 @@ static int walt_lb_find_busiest_cpu(int dst_cpu, const cpumask_t *src_mask, int
|
|||
|
||||
if (dst_wrq->cluster->id == fsrc_wrq->cluster->id)
|
||||
busiest_cpu = walt_lb_find_busiest_similar_cap_cpu(dst_cpu,
|
||||
src_mask, has_misfit);
|
||||
src_mask, has_misfit, is_newidle);
|
||||
else if (dst_wrq->cluster->id > fsrc_wrq->cluster->id)
|
||||
busiest_cpu = walt_lb_find_busiest_from_lower_cap_cpu(dst_cpu,
|
||||
src_mask, has_misfit);
|
||||
src_mask, has_misfit, is_newidle);
|
||||
else
|
||||
busiest_cpu = walt_lb_find_busiest_from_higher_cap_cpu(dst_cpu,
|
||||
src_mask, has_misfit);
|
||||
src_mask, has_misfit, is_newidle);
|
||||
|
||||
return busiest_cpu;
|
||||
}
|
||||
|
|
@ -830,7 +832,7 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
*/
|
||||
if (num_sched_clusters <= 2) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][0],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
|
||||
|
|
@ -839,7 +841,7 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
find_next_cluster = (order_index == 0) ? enough_idle : 1;
|
||||
if (find_next_cluster) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu,
|
||||
&cpu_array[order_index][1], &has_misfit);
|
||||
&cpu_array[order_index][1], &has_misfit, true);
|
||||
if (busy_cpu != -1 && (enough_idle || has_misfit))
|
||||
goto found_busy_cpu;
|
||||
}
|
||||
|
|
@ -850,13 +852,13 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
|
||||
if (order_index == 0) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][0],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
|
||||
if (enough_idle) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][1],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
}
|
||||
|
|
@ -866,7 +868,7 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
* cluster. In case no idle is found, pull it in.
|
||||
*/
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][2],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1) {
|
||||
first_idle =
|
||||
find_first_idle_if_others_are_busy(&cpu_array[order_index][1]);
|
||||
|
|
@ -877,20 +879,20 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
}
|
||||
} else if (order_index == 2) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][0],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
|
||||
/* help gold only if prime has had enough idle or gold has a misfit */
|
||||
has_misfit = false;
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][1],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1 && (enough_idle || has_misfit))
|
||||
goto found_busy_cpu;
|
||||
|
||||
/* help the farthest cluster indirectly if it needs help */
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][2],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1) {
|
||||
first_idle =
|
||||
find_first_idle_if_others_are_busy(&cpu_array[order_index][1]);
|
||||
|
|
@ -898,20 +900,21 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
|||
}
|
||||
} else {
|
||||
busy_cpu =
|
||||
walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][0], &has_misfit);
|
||||
walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][0],
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
|
||||
if (enough_idle) {
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][1],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1)
|
||||
goto found_busy_cpu;
|
||||
}
|
||||
|
||||
has_misfit = false;
|
||||
busy_cpu = walt_lb_find_busiest_cpu(this_cpu, &cpu_array[order_index][2],
|
||||
&has_misfit);
|
||||
&has_misfit, true);
|
||||
if (busy_cpu != -1 && (enough_idle || has_misfit))
|
||||
goto found_busy_cpu;
|
||||
}
|
||||
|
|
@ -1008,7 +1011,7 @@ static void walt_find_busiest_queue(void *unused, int dst_cpu,
|
|||
* remain same.
|
||||
*/
|
||||
cpumask_and(&src_mask, sched_group_span(group), env_cpus);
|
||||
busiest_cpu = walt_lb_find_busiest_cpu(dst_cpu, &src_mask, &has_misfit);
|
||||
busiest_cpu = walt_lb_find_busiest_cpu(dst_cpu, &src_mask, &has_misfit, false);
|
||||
done:
|
||||
if (busiest_cpu != -1)
|
||||
*busiest = cpu_rq(busiest_cpu);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user