[PATCH v3] cpufreq: schedutil: Serialize start against rate limit updates

From: Hui Su

Date: Mon Oct 12 2026 - 23:44:16 EST


rate_limit_us_store() updates the tunable and freq_update_delay_ns under
update_lock, but sugov_start() reads the tunable without it. Startup can
therefore overwrite the new delay with one based on a stale value.

Serialize the startup update with sysfs stores by taking update_lock in a
schedutil-local wrapper.

Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data")
Reviewed-by: Zhongqiu Han <zhongqiu.han@xxxxxxxxxxxxxxxx>
Signed-off-by: Hui Su <sh_def@xxxxxxx>
---
Changes in v3:
- Use a schedutil-local scoped wrapper and clarify the locking comment.

v2: https://lore.kernel.org/lkml/20261007155820.3194105-1-sh_def@xxxxxxx/
---
kernel/sched/cpufreq_schedutil.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 49ccd6f1c185..1d0878dad4b0 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -73,6 +73,16 @@ 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
+ * overwriting the new delay with one based on an old tunable value.
+ */
+ 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 +871,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;

base-commit: 63de2367f6d280904a9c5e5bbc7c75bb91c5b3d8
--
2.55.0