From 5e6a0f39fb37dd2d38bc4160835dfbeeba619bfd Mon Sep 17 00:00:00 2001 From: Stephen Dickey Date: Mon, 17 Apr 2023 22:14:40 -0700 Subject: [PATCH 1/2] sched/walt: core control nr_busy calculation The nr_busy calculation was being double accounted for titaniums, since it re-ran the loop to count nr_busy, for each cpu in the cluster. The original design of eval_need was to perform this operation once per cluster, using the lru mechanism to traverse the cpus in the list exactly once. During refactoring, the extra iteration was included. Restore the original intention behind this code from eval_need. Traverse the lru list exactly once, one time for each cpu in the cluster. Change-Id: If97ccbba840827cdfd3a874d4f9cfe85f67a0999 Signed-off-by: Stephen Dickey --- kernel/sched/walt/core_ctl.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/kernel/sched/walt/core_ctl.c b/kernel/sched/walt/core_ctl.c index 5c51f89e6725..b5cb9a38558a 100644 --- a/kernel/sched/walt/core_ctl.c +++ b/kernel/sched/walt/core_ctl.c @@ -908,25 +908,21 @@ static int compute_cluster_nr_strict_need(int index) */ static int compute_cluster_nr_busy(int index) { - int cpu; struct cluster_data *cluster = &cluster_state[index]; struct cpu_data *c; unsigned int thres_idx; int nr_busy = 0; - for_each_cpu(cpu, &cluster->cpu_mask) { - cluster->active_cpus = get_active_cpu_count(cluster); - thres_idx = cluster->active_cpus ? cluster->active_cpus - 1 : 0; - list_for_each_entry(c, &cluster->lru, sib) { + cluster->active_cpus = get_active_cpu_count(cluster); + thres_idx = cluster->active_cpus ? cluster->active_cpus - 1 : 0; + list_for_each_entry(c, &cluster->lru, sib) { + if (c->busy_pct >= cluster->busy_up_thres[thres_idx] || + sched_cpu_high_irqload(c->cpu)) + c->is_busy = true; + else if (c->busy_pct < cluster->busy_down_thres[thres_idx]) + c->is_busy = false; - if (c->busy_pct >= cluster->busy_up_thres[thres_idx] || - sched_cpu_high_irqload(c->cpu)) - c->is_busy = true; - else if (c->busy_pct < cluster->busy_down_thres[thres_idx]) - c->is_busy = false; - - nr_busy += c->is_busy; - } + nr_busy += c->is_busy; } return nr_busy; From 44b010a35995cf00b62552ab0333b135a5524384 Mon Sep 17 00:00:00 2001 From: Stephen Dickey Date: Tue, 11 Apr 2023 15:27:51 -0700 Subject: [PATCH 2/2] sched/walt: do not include partially halted cpus in busy calculation Core Control sums the number of cpus in the cluster that are busy, and calculates a nr_busy value for that cluster forming the basis for the apply_task_need calculation. This busy value has a strong impact on whether a cpu is halted or not. Partially halted cpus will be running small tasks. The decision to move into a fully unhalted state is being impacted by tasks that should not be included in the decision to unhalt a cpu. Update the busy calculation for the cluster such that when a visited cpu in the cluster is partially halted, the busy pct of the cpu is ignored. Change-Id: I8aed8412a8baa071625921624368b1841d7fcbf2 Signed-off-by: Stephen Dickey --- kernel/sched/walt/core_ctl.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/kernel/sched/walt/core_ctl.c b/kernel/sched/walt/core_ctl.c index b5cb9a38558a..7220f61bed11 100644 --- a/kernel/sched/walt/core_ctl.c +++ b/kernel/sched/walt/core_ctl.c @@ -916,13 +916,17 @@ static int compute_cluster_nr_busy(int index) cluster->active_cpus = get_active_cpu_count(cluster); thres_idx = cluster->active_cpus ? cluster->active_cpus - 1 : 0; list_for_each_entry(c, &cluster->lru, sib) { - if (c->busy_pct >= cluster->busy_up_thres[thres_idx] || - sched_cpu_high_irqload(c->cpu)) - c->is_busy = true; - else if (c->busy_pct < cluster->busy_down_thres[thres_idx]) + if (cpu_partial_halted(c->cpu)) { c->is_busy = false; + } else { + if (c->busy_pct >= cluster->busy_up_thres[thres_idx] || + sched_cpu_high_irqload(c->cpu)) + c->is_busy = true; + else if (c->busy_pct < cluster->busy_down_thres[thres_idx]) + c->is_busy = false; - nr_busy += c->is_busy; + nr_busy += c->is_busy; + } } return nr_busy;