diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 49ccd6f1c185..14405a614991 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -73,6 +73,18 @@ static void sugov_update_rate_limit_us(struct sugov_policy *sg_policy) (s64)sg_policy->tunables->rate_limit_us * NSEC_PER_USEC; } +static void sugov_update_rate_limit_us_sync(struct sugov_policy *sg_policy) +{ + /* + * Serialize with rate_limit_us_store() to prevent this path from using + * a stale rate limit tunable value to set the limit for the given + * policy. + */ + guard(mutex)(&sg_policy->tunables->attr_set.update_lock); + + sugov_update_rate_limit_us(sg_policy); +} + static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) { s64 delta_ns; @@ -861,7 +873,7 @@ static int sugov_start(struct cpufreq_policy *policy) void (*uu)(struct update_util_data *data, u64 time, unsigned int flags); unsigned int cpu; - sugov_update_rate_limit_us(sg_policy); + sugov_update_rate_limit_us_sync(sg_policy); sg_policy->last_freq_update_time = 0; sg_policy->next_freq = 0; sg_policy->work_in_progress = false;