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>
Tento commit je obsažen v:
@@ -415,7 +415,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;
|
||||
@@ -426,7 +426,8 @@ static int walt_lb_find_busiest_similar_cap_cpu(int dst_cpu, const cpumask_t *sr
|
||||
wrq = (struct walt_rq *) cpu_rq(i)->android_vendor_data1;
|
||||
trace_walt_lb_cpu_util(i, wrq);
|
||||
|
||||
if (cpu_rq(i)->nr_running < 2 || !cpu_rq(i)->cfs.h_nr_running)
|
||||
if ((dst_cpu == i) || (cpu_rq(i)->nr_running < 2)
|
||||
|| !cpu_rq(i)->cfs.h_nr_running)
|
||||
continue;
|
||||
|
||||
util = walt_lb_cpu_util(i);
|
||||
@@ -441,7 +442,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;
|
||||
@@ -501,7 +502,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;
|
||||
@@ -510,6 +511,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
|
||||
@@ -541,7 +543,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) &&
|
||||
@@ -568,20 +570,21 @@ 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;
|
||||
|
||||
if (capacity_orig_of(dst_cpu) == capacity_orig_of(fsrc_cpu))
|
||||
busiest_cpu = walt_lb_find_busiest_similar_cap_cpu(dst_cpu,
|
||||
src_mask, has_misfit);
|
||||
src_mask, has_misfit, is_newidle);
|
||||
else if (capacity_orig_of(dst_cpu) > capacity_orig_of(fsrc_cpu))
|
||||
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;
|
||||
}
|
||||
@@ -799,9 +802,13 @@ static void walt_newidle_balance(void *unused, struct rq *this_rq,
|
||||
* check if any tasks are queued on this and bail out
|
||||
* early.
|
||||
*/
|
||||
|
||||
//TODO: if we are in newidle we can skip all these ?
|
||||
if (walt_balance_rt(this_rq) || this_rq->nr_running)
|
||||
goto rt_pulled;
|
||||
|
||||
|
||||
//TODO: ! here we are checking not overload and exiting ?
|
||||
if (!READ_ONCE(this_rq->rd->overload))
|
||||
goto repin;
|
||||
|
||||
@@ -819,7 +826,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;
|
||||
|
||||
@@ -828,7 +835,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;
|
||||
}
|
||||
@@ -839,13 +846,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;
|
||||
}
|
||||
@@ -855,7 +862,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]);
|
||||
@@ -866,20 +873,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]);
|
||||
@@ -887,20 +894,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;
|
||||
}
|
||||
@@ -969,7 +977,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);
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele