diff --git a/kernel/sched/walt/cpufreq_walt.c b/kernel/sched/walt/cpufreq_walt.c index 57692b62949c..53b477fcbce0 100644 --- a/kernel/sched/walt/cpufreq_walt.c +++ b/kernel/sched/walt/cpufreq_walt.c @@ -199,13 +199,25 @@ static void waltgov_deferred_update(struct waltgov_policy *wg_policy, u64 time, } #define TARGET_LOAD 80 +static inline unsigned long walt_map_util_freq(unsigned long util, + unsigned long fmax, unsigned long cap, + int cpu) +{ + if (is_min_capacity_cpu(cpu) && + util >= sysctl_sched_silver_thres && + cpu_util_rt(cpu_rq(cpu)) < (cap >> 2)) + return (fmax + (fmax >> 4)) * util / cap; + return (fmax + (fmax >> 2)) * util / cap; +} + static unsigned int get_next_freq(struct waltgov_policy *wg_policy, - unsigned long util, unsigned long max) + unsigned long util, unsigned long max, + struct waltgov_cpu *wg_cpu) { struct cpufreq_policy *policy = wg_policy->policy; unsigned int freq = policy->cpuinfo.max_freq; - freq = map_util_freq(util, freq, max); + freq = walt_map_util_freq(util, freq, max, wg_cpu->cpu); trace_waltgov_next_freq(policy->cpu, util, max, freq, policy->min, policy->max, wg_policy->cached_raw_freq, wg_policy->need_freq_update); @@ -269,7 +281,13 @@ static inline unsigned long target_util(struct waltgov_policy *wg_policy, unsigned long util; util = freq_to_util(wg_policy, freq); - util = mult_frac(util, TARGET_LOAD, 100); + + if (wg_policy->max == min_max_possible_capacity && + util >= sysctl_sched_silver_thres) + util = mult_frac(util, 94, 100); + else + util = mult_frac(util, TARGET_LOAD, 100); + return util; } @@ -308,7 +326,7 @@ static unsigned int waltgov_next_freq_shared(struct waltgov_cpu *wg_cpu, u64 tim waltgov_walt_adjust(j_wg_cpu, j_util, j_nl, &util, &max); } - return get_next_freq(wg_policy, util, max); + return get_next_freq(wg_policy, util, max, wg_cpu); } static void waltgov_update_freq(struct waltgov_callback *cb, u64 time, diff --git a/kernel/sched/walt/sysctl.c b/kernel/sched/walt/sysctl.c index 578af892a5a8..8bfe41973a78 100644 --- a/kernel/sched/walt/sysctl.c +++ b/kernel/sched/walt/sysctl.c @@ -48,6 +48,7 @@ unsigned int __read_mostly sysctl_sched_coloc_downmigrate_ns; unsigned int __read_mostly sysctl_sched_group_downmigrate_pct; unsigned int __read_mostly sysctl_sched_group_upmigrate_pct; unsigned int __read_mostly sysctl_sched_window_stats_policy; +unsigned int __read_mostly sysctl_sched_silver_thres; unsigned int sysctl_sched_ravg_window_nr_ticks; unsigned int sysctl_sched_walt_rotate_big_tasks; unsigned int sysctl_sched_task_unfilter_period; @@ -467,6 +468,15 @@ struct ctl_table walt_table[] = { .extra1 = SYSCTL_ZERO, .extra2 = &four, }, + { + .procname = "sched_silver_thres", + .data = &sysctl_sched_silver_thres, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = &one_thousand, + }, { .procname = "sched_group_upmigrate", .data = &sysctl_sched_group_upmigrate_pct, @@ -813,6 +823,8 @@ void walt_tunables(void) sysctl_sched_window_stats_policy = WINDOW_STATS_MAX_RECENT_AVG; + sysctl_sched_silver_thres = 1000; + sysctl_sched_ravg_window_nr_ticks = (HZ / NR_WINDOWS_PER_SEC); sched_load_granule = DEFAULT_SCHED_RAVG_WINDOW / NUM_LOAD_INDICES; diff --git a/kernel/sched/walt/trace.h b/kernel/sched/walt/trace.h index d382b5fd018f..199c882f61a1 100644 --- a/kernel/sched/walt/trace.h +++ b/kernel/sched/walt/trace.h @@ -695,6 +695,7 @@ TRACE_EVENT(waltgov_next_freq, __field(unsigned int, policy_max_freq) __field(unsigned int, cached_raw_freq) __field(bool, need_freq_update) + __field(unsigned int, rt_util) ), TP_fast_assign( __entry->cpu = cpu; @@ -705,8 +706,9 @@ TRACE_EVENT(waltgov_next_freq, __entry->policy_max_freq = policy_max_freq; __entry->cached_raw_freq = cached_raw_freq; __entry->need_freq_update = need_freq_update; + __entry->rt_util = cpu_util_rt(cpu_rq(cpu)); ), - TP_printk("cpu=%u util=%lu max=%lu freq=%u policy_min_freq=%u policy_max_freq=%u cached_raw_freq=%u need_update=%d", + TP_printk("cpu=%u util=%lu max=%lu freq=%u policy_min_freq=%u policy_max_freq=%u cached_raw_freq=%u need_update=%d rt_util=%u", __entry->cpu, __entry->util, __entry->max, @@ -714,7 +716,8 @@ TRACE_EVENT(waltgov_next_freq, __entry->policy_min_freq, __entry->policy_max_freq, __entry->cached_raw_freq, - __entry->need_freq_update) + __entry->need_freq_update, + __entry->rt_util) ); TRACE_EVENT(walt_active_load_balance, diff --git a/kernel/sched/walt/walt.h b/kernel/sched/walt/walt.h index f1dca89e2f0e..7eb09cf78116 100644 --- a/kernel/sched/walt/walt.h +++ b/kernel/sched/walt/walt.h @@ -204,6 +204,7 @@ extern unsigned int __read_mostly sched_load_granule; extern unsigned int sysctl_sched_min_task_util_for_boost; /* 0.68ms default for 20ms window size scaled to 1024 */ extern unsigned int sysctl_sched_min_task_util_for_colocation; +extern unsigned int __read_mostly sysctl_sched_silver_thres; extern unsigned int sysctl_sched_busy_hyst_enable_cpus; extern unsigned int sysctl_sched_busy_hyst; extern unsigned int sysctl_sched_coloc_busy_hyst_enable_cpus;