From 48c24c731637d5dc3bd5ce2ef1a521554f32ee02 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Tue, 14 Jun 2022 23:47:29 +0530 Subject: [PATCH] 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 Signed-off-by: Sai Harshini Nimmala --- kernel/sched/walt/walt_lb.c | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/kernel/sched/walt/walt_lb.c b/kernel/sched/walt/walt_lb.c index a3020210bbc3..ff89294cdc7e 100644 --- a/kernel/sched/walt/walt_lb.c +++ b/kernel/sched/walt/walt_lb.c @@ -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);