From 066f712e43bf87de175b7026bb4c62b412345474 Mon Sep 17 00:00:00 2001 From: Syed Rameez Mustafa Date: Tue, 7 Jun 2016 16:03:17 -0700 Subject: [PATCH] sched: Add multiple load reporting policies for cpu frequency The previous patches in this series introduce the mechanics of CPU load tracking without fixups for intra cluster migration and top task load tracking. Add a tunable that dictates what of the above needs to be considered when reporting load to the governor. The default policy is to take the maximum of the CPU load and top task load. Change-Id: Ie585a11ed774b929910d04c41471db3a2a102ec5 Signed-off-by: Syed Rameez Mustafa --- include/linux/sched/sysctl.h | 1 + kernel/sched/hmp.c | 30 +++++++++++++++++++++++++++++- kernel/sched/sched.h | 4 ++++ kernel/sysctl.c | 8 ++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 9fe71c774543..6848454c5447 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -44,6 +44,7 @@ extern unsigned int sysctl_sched_wake_to_idle; #ifdef CONFIG_SCHED_HMP extern int sysctl_sched_freq_inc_notify; extern int sysctl_sched_freq_dec_notify; +extern unsigned int sysctl_sched_freq_reporting_policy; extern unsigned int sysctl_sched_window_stats_policy; extern unsigned int sysctl_sched_ravg_hist_size; extern unsigned int sysctl_sched_cpu_high_irqload; diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index dffe18ebab74..b3dad1289ed4 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -789,6 +789,12 @@ __read_mostly unsigned int sysctl_sched_new_task_windows = 5; #define SCHED_FREQ_ACCOUNT_WAIT_TIME 0 +/* + * This governs what load needs to be used when reporting CPU busy time + * to the cpufreq governor. + */ +__read_mostly unsigned int sysctl_sched_freq_reporting_policy; + /* * For increase, send notification if * freq_required - cur_freq > sysctl_sched_freq_inc_notify @@ -2198,7 +2204,7 @@ void clear_top_tasks_bitmap(unsigned long *bitmap) * Note that sched_load_granule can change underneath us if we are not * holding any runqueue locks while calling the two functions below. */ -static u32 __maybe_unused top_task_load(struct rq *rq) +static u32 top_task_load(struct rq *rq) { int index = rq->prev_top; u8 prev = 1 - rq->curr_table; @@ -3268,6 +3274,26 @@ static inline void account_load_subtractions(struct rq *rq) BUG_ON((s64)rq->nt_curr_runnable_sum < 0); } +static inline u64 freq_policy_load(struct rq *rq, u64 load) +{ + unsigned int reporting_policy = sysctl_sched_freq_reporting_policy; + + switch (reporting_policy) { + case FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK: + load = max_t(u64, load, top_task_load(rq)); + break; + case FREQ_REPORT_TOP_TASK: + load = top_task_load(rq); + break; + case FREQ_REPORT_CPU_LOAD: + break; + default: + WARN_ON_ONCE(1); + } + + return load; +} + static inline void sync_window_start(struct rq *rq, struct group_cpu_time *cpu_time); @@ -3385,6 +3411,8 @@ void sched_get_cpus_busy(struct sched_load *busy, load[i] += group_load[i]; nload[i] += ngload[i]; + + load[i] = freq_policy_load(rq, load[i]); /* * Scale load in reference to cluster max_possible_freq. * diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 4fd56b04c336..471dc9faab35 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1034,6 +1034,10 @@ static inline void sched_ttwu_pending(void) { } #define WINDOW_STATS_AVG 3 #define WINDOW_STATS_INVALID_POLICY 4 +#define FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK 0 +#define FREQ_REPORT_CPU_LOAD 1 +#define FREQ_REPORT_TOP_TASK 2 + #define MAJOR_TASK_PCT 85 #define SCHED_UPMIGRATE_MIN_NICE 15 #define EXITING_TASK_MARKER 0xdeaddead diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 587dbe09c47d..c72cb2053da7 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -296,6 +296,14 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, #ifdef CONFIG_SCHED_HMP + { + .procname = "sched_freq_reporting_policy", + .data = &sysctl_sched_freq_reporting_policy, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + }, { .procname = "sched_freq_inc_notify", .data = &sysctl_sched_freq_inc_notify,