From 4349ffdf244bc028fe96a645d7e00ccfe8618252 Mon Sep 17 00:00:00 2001 From: Shaleen Agrawal Date: Tue, 30 Aug 2022 14:45:09 -0700 Subject: [PATCH] kernel/sched/walt/energy-model: inflate cost for 1.6Ghz by 3x Certain frequencies in min-cap cpus draw excessive power and are more costly to the device's performance than indicated by the energy model. For silver frequencies above a threshold, inflate the cost by a percentage to create a steep power curve, favoring golds at lower frequencies. For example, to raise the cost for frequencies above 1.6GHz by 3x: echo 300 > /proc/sys/walt/sched_em_inflate_pct echo 220 > /proc/sys/walt/sched_em_inflate_thres Change-Id: Ia10a818ab2f217ffa3039667f52566d9894e5047 Signed-off-by: Shaleen Agrawal Signed-off-by: Stephen Dickey --- kernel/sched/walt/sysctl.c | 21 +++++++++++++++++++++ kernel/sched/walt/walt.h | 2 ++ kernel/sched/walt/walt_cfs.c | 19 ++++++++++++++----- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/kernel/sched/walt/sysctl.c b/kernel/sched/walt/sysctl.c index 56a5608bf11f..38b0c731eae4 100644 --- a/kernel/sched/walt/sysctl.c +++ b/kernel/sched/walt/sysctl.c @@ -19,6 +19,7 @@ static int __maybe_unused two = 2; static int __maybe_unused four = 4; static int one_hundred = 100; static int one_thousand = 1000; +static int one_thousand_twenty_four = 1024; static int two_thousand = 2000; /* @@ -77,6 +78,8 @@ unsigned int sysctl_sched_long_running_rt_task_ms; unsigned int sysctl_sched_idle_enough; unsigned int sysctl_sched_cluster_util_thres_pct; unsigned int sysctl_ed_boost_pct; +unsigned int sysctl_em_inflate_pct = 100; +unsigned int sysctl_em_inflate_thres = 1024; /* range is [1 .. INT_MAX] */ static int sysctl_task_read_pid = 1; @@ -1011,6 +1014,24 @@ struct ctl_table walt_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = &one_hundred, }, + { + .procname = "sched_em_inflate_pct", + .data = &sysctl_em_inflate_pct, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_douintvec_minmax, + .extra1 = &one_hundred, + .extra2 = &one_thousand, + }, + { + .procname = "sched_em_inflate_thres", + .data = &sysctl_em_inflate_thres, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_douintvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = &one_thousand_twenty_four, + }, { } }; diff --git a/kernel/sched/walt/walt.h b/kernel/sched/walt/walt.h index dbc334ab649e..9e074bcc5a14 100644 --- a/kernel/sched/walt/walt.h +++ b/kernel/sched/walt/walt.h @@ -220,6 +220,8 @@ extern unsigned int sysctl_sched_conservative_pl; extern unsigned int sysctl_sched_hyst_min_coloc_ns; extern unsigned int sysctl_sched_long_running_rt_task_ms; extern unsigned int sysctl_ed_boost_pct; +extern unsigned int sysctl_em_inflate_pct; +extern unsigned int sysctl_em_inflate_thres; extern int cpufreq_walt_set_adaptive_freq(unsigned int cpu, unsigned int adaptive_low_freq, unsigned int adaptive_high_freq); diff --git a/kernel/sched/walt/walt_cfs.c b/kernel/sched/walt/walt_cfs.c index 9e6639eaceb9..d2c2b339ecbd 100644 --- a/kernel/sched/walt/walt_cfs.c +++ b/kernel/sched/walt/walt_cfs.c @@ -568,6 +568,16 @@ cpu_util_next_walt_prs(int cpu, struct task_struct *p, int dst_cpu, bool prev_ds return util; } +static inline unsigned long get_util_to_cost(int cpu, unsigned long util) +{ + struct walt_rq *wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1; + + if (cpu == 0 && util > sysctl_em_inflate_thres) + return mult_frac(wrq->cluster->util_to_cost[util], sysctl_em_inflate_pct, 100); + else + return wrq->cluster->util_to_cost[util]; +} + /** * walt_em_cpu_energy() - Estimates the energy consumed by the CPUs of a performance domain @@ -586,9 +596,8 @@ static inline unsigned long walt_em_cpu_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util, struct compute_energy_output *output, unsigned int x) { - unsigned long scale_cpu; + unsigned long scale_cpu, cost; int cpu; - struct walt_rq *wrq; if (!sum_util) return 0; @@ -651,14 +660,14 @@ static inline unsigned long walt_em_cpu_energy(struct em_perf_domain *pd, if (max_util >= 1024) max_util = 1023; - wrq = (struct walt_rq *) cpu_rq(cpu)->android_vendor_data1; + cost = get_util_to_cost(cpu, max_util); if (output) { - output->cost[x] = wrq->cluster->util_to_cost[max_util]; + output->cost[x] = cost; output->max_util[x] = max_util; output->sum_util[x] = sum_util; } - return wrq->cluster->util_to_cost[max_util] * sum_util / scale_cpu; + return cost * sum_util / scale_cpu; } /*