diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 765ec8146764..e757514f45d3 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -35,6 +35,7 @@ struct sugov_policy { s64 down_rate_delay_ns; unsigned int next_freq; unsigned int cached_raw_freq; + unsigned int prev_cached_raw_freq; /* The next fields are only needed if fast switch cannot be used: */ struct irq_work irq_work; @@ -134,8 +135,8 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, return false; if (sugov_up_down_rate_limit(sg_policy, time, next_freq)) { - /* Reset cached freq as next_freq is not changed */ - sg_policy->cached_raw_freq = 0; + /* Restore cached freq as next_freq is not changed */ + sg_policy->cached_raw_freq = sg_policy->prev_cached_raw_freq; return false; } @@ -213,6 +214,7 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, return sg_policy->next_freq; sg_policy->need_freq_update = false; + sg_policy->prev_cached_raw_freq = sg_policy->cached_raw_freq; sg_policy->cached_raw_freq = freq; return cpufreq_driver_resolve_freq(policy, freq); } @@ -520,8 +522,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, if (busy && next_f < sg_policy->next_freq) { next_f = sg_policy->next_freq; - /* Reset cached freq as next_freq has changed */ - sg_policy->cached_raw_freq = 0; + /* Restore cached freq as next_freq has changed */ + sg_policy->cached_raw_freq = sg_policy->prev_cached_raw_freq; } /* @@ -929,6 +931,7 @@ static int sugov_start(struct cpufreq_policy *policy) sg_policy->limits_changed = false; sg_policy->need_freq_update = false; sg_policy->cached_raw_freq = 0; + sg_policy->prev_cached_raw_freq = 0; for_each_cpu(cpu, policy->cpus) { struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);