From 8cd1d7ef162d0911d18cf971c4a34c07bb994a80 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Mon, 14 Dec 2015 14:23:24 +0530 Subject: [PATCH] sched: Take cluster's minimum power into account for optimizing sbc() The select_best_cpu() algorithm iterates over all the clusters and selects the most power efficient CPU that satisfies the task needs. During the search, skip the next cluster if its minimum power cost is higher than the power cost of an eligible CPU found in the previous cluster. In a b.L system, if the BIG cluster minimum power cost is higher than the maximum power cost of the little cluster, this optimization avoids searching the BIG cluster if an eligible CPU is found in the little cluster. Change-Id: I5e3755f107edb6c72180edbec2a658be931c276d Signed-off-by: Pavankumar Kondeti --- kernel/sched/core.c | 7 ++++++- kernel/sched/fair.c | 14 +++++++++++--- kernel/sched/sched.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3eb27a016003..76e265ad1abf 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1298,6 +1298,7 @@ static struct sched_cluster init_cluster = { .list = LIST_HEAD_INIT(init_cluster.list), .id = 0, .max_power_cost = 1, + .min_power_cost = 1, .capacity = 1024, .max_possible_capacity = 1024, .efficiency = 1, @@ -1398,9 +1399,12 @@ static void sort_clusters(void) INIT_LIST_HEAD(&new_head); - for_each_sched_cluster(cluster) + for_each_sched_cluster(cluster) { cluster->max_power_cost = power_cost(cluster_first_cpu(cluster), max_task_load()); + cluster->min_power_cost = power_cost(cluster_first_cpu(cluster), + 0); + } move_list(&new_head, &cluster_head, true); @@ -1442,6 +1446,7 @@ static struct sched_cluster *alloc_new_cluster(const struct cpumask *cpus) INIT_LIST_HEAD(&cluster->list); cluster->max_power_cost = 1; + cluster->min_power_cost = 1; cluster->capacity = 1024; cluster->max_possible_capacity = 1024; cluster->efficiency = 1; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1cb4d18b1039..fc31d1b48a2d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3296,7 +3296,8 @@ struct cpu_select_env *env, struct cluster_cpu_stats *stats) } struct sched_cluster * -next_best_cluster(struct sched_cluster *cluster, struct cpu_select_env *env) +next_best_cluster(struct sched_cluster *cluster, struct cpu_select_env *env, + struct cluster_cpu_stats *stats) { struct sched_cluster *next = NULL; @@ -3310,9 +3311,16 @@ next_best_cluster(struct sched_cluster *cluster, struct cpu_select_env *env) return NULL; next = next_candidate(env->candidate_list, 0, num_clusters); - if (next) + if (next) { + if (next->min_power_cost > stats->min_cost) { + clear_bit(next->id, env->candidate_list); + next = NULL; + continue; + } + if (skip_cluster(next, env)) next = NULL; + } } while (!next); env->task_load = scale_load_to_cpu(task_load(env->p), @@ -3529,7 +3537,7 @@ retry: do { find_best_cpu_in_cluster(cluster, &env, &stats); - } while ((cluster = next_best_cluster(cluster, &env))); + } while ((cluster = next_best_cluster(cluster, &env, &stats))); if (stats.best_idle_cpu >= 0) { target = stats.best_idle_cpu; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 2390f927f8c2..0185f664191b 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -374,6 +374,7 @@ struct sched_cluster { struct cpumask cpus; int id; int max_power_cost; + int min_power_cost; int max_possible_capacity; int capacity; int efficiency; /* Differentiate cpus with different IPC capability */ -- 2.11.0