Loading kernel/sched/cpufreq_schedutil.c +60 −47 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/sched/cpufreq.h> #include <trace/events/power.h> #include <linux/sched/sysctl.h> struct sugov_tunables { struct gov_attr_set attr_set; Loading Loading @@ -165,6 +166,58 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, return true; } static unsigned long freq_to_util(struct sugov_policy *sg_policy, unsigned int freq) { return mult_frac(sg_policy->max, freq, sg_policy->policy->cpuinfo.max_freq); } #define KHZ 1000 static void sugov_track_cycles(struct sugov_policy *sg_policy, unsigned int prev_freq, u64 upto) { u64 delta_ns, cycles; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; /* Track cycles in current window */ delta_ns = upto - sg_policy->last_cyc_update_time; cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ); sg_policy->curr_cycles += cycles; sg_policy->last_cyc_update_time = upto; } static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws, unsigned int prev_freq) { u64 last_ws = sg_policy->last_ws; unsigned int avg_freq; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; WARN_ON(curr_ws < last_ws); if (curr_ws <= last_ws) return; /* If we skipped some windows */ if (curr_ws > (last_ws + sched_ravg_window)) { avg_freq = prev_freq; /* Reset tracking history */ sg_policy->last_cyc_update_time = curr_ws; } else { sugov_track_cycles(sg_policy, prev_freq, curr_ws); avg_freq = sg_policy->curr_cycles; avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ); } sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq); sg_policy->curr_cycles = 0; sg_policy->last_ws = curr_ws; } static void sugov_fast_switch(struct sugov_policy *sg_policy, u64 time, unsigned int next_freq) { Loading @@ -174,6 +227,7 @@ static void sugov_fast_switch(struct sugov_policy *sg_policy, u64 time, if (!sugov_update_next_freq(sg_policy, time, next_freq)) return; sugov_track_cycles(sg_policy, sg_policy->policy->cur, time); next_freq = cpufreq_driver_fast_switch(policy, next_freq); if (!next_freq) return; Loading Loading @@ -504,51 +558,6 @@ static bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; } #endif /* CONFIG_NO_HZ_COMMON */ static unsigned long freq_to_util(struct sugov_policy *sg_policy, unsigned int freq) { return mult_frac(sg_policy->max, freq, sg_policy->policy->cpuinfo.max_freq); } #define KHZ 1000 static void sugov_track_cycles(struct sugov_policy *sg_policy, unsigned int prev_freq, u64 upto) { u64 delta_ns, cycles; /* Track cycles in current window */ delta_ns = upto - sg_policy->last_cyc_update_time; cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ); sg_policy->curr_cycles += cycles; sg_policy->last_cyc_update_time = upto; } static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws, unsigned int prev_freq) { u64 last_ws = sg_policy->last_ws; unsigned int avg_freq; WARN_ON(curr_ws < last_ws); if (curr_ws <= last_ws) return; /* If we skipped some windows */ if (curr_ws > (last_ws + sched_ravg_window)) { avg_freq = prev_freq; /* Reset tracking history */ sg_policy->last_cyc_update_time = curr_ws; } else { sugov_track_cycles(sg_policy, prev_freq, curr_ws); avg_freq = sg_policy->curr_cycles; avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ); } sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq); sg_policy->curr_cycles = 0; sg_policy->last_ws = curr_ws; } #define NL_RATIO 75 #define DEFAULT_HISPEED_LOAD 90 static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util, Loading @@ -560,6 +569,9 @@ static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util, unsigned long cpu_util = sg_cpu->util; bool is_hiload; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; is_hiload = (cpu_util >= mult_frac(sg_policy->avg_cap, sg_policy->tunables->hispeed_load, 100)); Loading Loading @@ -604,7 +616,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, if (!sugov_should_update_freq(sg_policy, time)) return; busy = sugov_cpu_is_busy(sg_cpu); busy = use_pelt() && sugov_cpu_is_busy(sg_cpu); sg_cpu->util = util = sugov_get_util(sg_cpu); max = sg_cpu->max; Loading Loading @@ -736,7 +748,8 @@ sugov_update_shared(struct update_util_data *hook, u64 time, unsigned int flags) sg_cpu->max, sg_cpu->walt_load.nl, sg_cpu->walt_load.pl, flags); if (sugov_should_update_freq(sg_policy, time)) { if (sugov_should_update_freq(sg_policy, time) && !(flags & SCHED_CPUFREQ_CONTINUE)) { next_f = sugov_next_freq_shared(sg_cpu, time); if (sg_policy->policy->fast_switch_enabled) Loading Loading
kernel/sched/cpufreq_schedutil.c +60 −47 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/sched/cpufreq.h> #include <trace/events/power.h> #include <linux/sched/sysctl.h> struct sugov_tunables { struct gov_attr_set attr_set; Loading Loading @@ -165,6 +166,58 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, return true; } static unsigned long freq_to_util(struct sugov_policy *sg_policy, unsigned int freq) { return mult_frac(sg_policy->max, freq, sg_policy->policy->cpuinfo.max_freq); } #define KHZ 1000 static void sugov_track_cycles(struct sugov_policy *sg_policy, unsigned int prev_freq, u64 upto) { u64 delta_ns, cycles; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; /* Track cycles in current window */ delta_ns = upto - sg_policy->last_cyc_update_time; cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ); sg_policy->curr_cycles += cycles; sg_policy->last_cyc_update_time = upto; } static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws, unsigned int prev_freq) { u64 last_ws = sg_policy->last_ws; unsigned int avg_freq; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; WARN_ON(curr_ws < last_ws); if (curr_ws <= last_ws) return; /* If we skipped some windows */ if (curr_ws > (last_ws + sched_ravg_window)) { avg_freq = prev_freq; /* Reset tracking history */ sg_policy->last_cyc_update_time = curr_ws; } else { sugov_track_cycles(sg_policy, prev_freq, curr_ws); avg_freq = sg_policy->curr_cycles; avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ); } sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq); sg_policy->curr_cycles = 0; sg_policy->last_ws = curr_ws; } static void sugov_fast_switch(struct sugov_policy *sg_policy, u64 time, unsigned int next_freq) { Loading @@ -174,6 +227,7 @@ static void sugov_fast_switch(struct sugov_policy *sg_policy, u64 time, if (!sugov_update_next_freq(sg_policy, time, next_freq)) return; sugov_track_cycles(sg_policy, sg_policy->policy->cur, time); next_freq = cpufreq_driver_fast_switch(policy, next_freq); if (!next_freq) return; Loading Loading @@ -504,51 +558,6 @@ static bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; } #endif /* CONFIG_NO_HZ_COMMON */ static unsigned long freq_to_util(struct sugov_policy *sg_policy, unsigned int freq) { return mult_frac(sg_policy->max, freq, sg_policy->policy->cpuinfo.max_freq); } #define KHZ 1000 static void sugov_track_cycles(struct sugov_policy *sg_policy, unsigned int prev_freq, u64 upto) { u64 delta_ns, cycles; /* Track cycles in current window */ delta_ns = upto - sg_policy->last_cyc_update_time; cycles = (prev_freq * delta_ns) / (NSEC_PER_SEC / KHZ); sg_policy->curr_cycles += cycles; sg_policy->last_cyc_update_time = upto; } static void sugov_calc_avg_cap(struct sugov_policy *sg_policy, u64 curr_ws, unsigned int prev_freq) { u64 last_ws = sg_policy->last_ws; unsigned int avg_freq; WARN_ON(curr_ws < last_ws); if (curr_ws <= last_ws) return; /* If we skipped some windows */ if (curr_ws > (last_ws + sched_ravg_window)) { avg_freq = prev_freq; /* Reset tracking history */ sg_policy->last_cyc_update_time = curr_ws; } else { sugov_track_cycles(sg_policy, prev_freq, curr_ws); avg_freq = sg_policy->curr_cycles; avg_freq /= sched_ravg_window / (NSEC_PER_SEC / KHZ); } sg_policy->avg_cap = freq_to_util(sg_policy, avg_freq); sg_policy->curr_cycles = 0; sg_policy->last_ws = curr_ws; } #define NL_RATIO 75 #define DEFAULT_HISPEED_LOAD 90 static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util, Loading @@ -560,6 +569,9 @@ static void sugov_walt_adjust(struct sugov_cpu *sg_cpu, unsigned long *util, unsigned long cpu_util = sg_cpu->util; bool is_hiload; if (unlikely(!sysctl_sched_use_walt_cpu_util)) return; is_hiload = (cpu_util >= mult_frac(sg_policy->avg_cap, sg_policy->tunables->hispeed_load, 100)); Loading Loading @@ -604,7 +616,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, if (!sugov_should_update_freq(sg_policy, time)) return; busy = sugov_cpu_is_busy(sg_cpu); busy = use_pelt() && sugov_cpu_is_busy(sg_cpu); sg_cpu->util = util = sugov_get_util(sg_cpu); max = sg_cpu->max; Loading Loading @@ -736,7 +748,8 @@ sugov_update_shared(struct update_util_data *hook, u64 time, unsigned int flags) sg_cpu->max, sg_cpu->walt_load.nl, sg_cpu->walt_load.pl, flags); if (sugov_should_update_freq(sg_policy, time)) { if (sugov_should_update_freq(sg_policy, time) && !(flags & SCHED_CPUFREQ_CONTINUE)) { next_f = sugov_next_freq_shared(sg_cpu, time); if (sg_policy->policy->fast_switch_enabled) Loading