From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C4AA2737E7 for ; Sat, 6 Sep 2025 16:25:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757175957; cv=none; b=uBW0xublHv9MVFOjw2F7mx7DVgublMLehjdhJM4lp/Zzvp4zlExWM/u16kJXv+kySYi0EOHLv7pI3X1968QpRe+TQ6o3ktkChVbwFivBWuDl+7Wrt0VS6s7lSIPbeOmTa82Yk7tDJSCT7fuZr01j8JoyXZql9JgCN89H4mVzgbI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757175957; c=relaxed/simple; bh=c5D82IzPbK89NH8tIChpRXE+5Xnq7zC6GKuCKnWPI44=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DQLld0vjB0dalmN6FQ8cped/EEO6ZYH9ZNneTFgh3JTKZ9puEqtmO7ZrcYiQt3ienUgehGBQJVuBcXyp94V9ICz/rWUMg6WHkhspse1e2/lg2RN7sc9qEYqj7AqYJGW6h9Pk3kzfPGvSdSG0QEd4ESGzIIOnBDHMifQ0omiqd7M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nt3M8K41; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nt3M8K41" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BBA19C4CEE7; Sat, 6 Sep 2025 16:25:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757175957; bh=c5D82IzPbK89NH8tIChpRXE+5Xnq7zC6GKuCKnWPI44=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nt3M8K41ycLjVdicmMfxAWw4Z4Ygb+aY7/zWNzMVUZPens4iOCYIBMw/fZ2rZKK1u uaiusaXOShL1LoaX4RPPdLY/oonoTMgX0MTDL7Vzbg7iU9Wkqq1b8MMbmQRIcsGq4z VR8ASGnjH/Cb8ueJ6zR7Ua7oBITyh1YjzRlIdNR4Yv0kOGaq5V7PfEnNfcP43ESGaC FqpNekbkmXtX0B0FsHk2fUY5VyWplXITDBKkV0BOe2o3JBVNnW1ntiIYp1Gdns8UaR ASRHXe9z95vz63jxHFZt57C9zlnEN7MeyOcVDdMizW5lYlXq35xYPHq0askD6zXlo6 eTsfiJ7U0T2FQ== From: Sasha Levin To: stable@vger.kernel.org Cc: "Rafael J. Wysocki" , Christian Loehle , Sasha Levin Subject: [PATCH 5.15.y] cpufreq/sched: Explicitly synchronize limits_changed flag handling Date: Sat, 6 Sep 2025 12:25:54 -0400 Message-ID: <20250906162554.151159-1-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <2025042157-spinout-petted-8c6b@gregkh> References: <2025042157-spinout-petted-8c6b@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: "Rafael J. Wysocki" [ Upstream commit 79443a7e9da3c9f68290a8653837e23aba0fa89f ] The handling of the limits_changed flag in struct sugov_policy needs to be explicitly synchronized to ensure that cpufreq policy limits updates will not be missed in some cases. Without that synchronization it is theoretically possible that the limits_changed update in sugov_should_update_freq() will be reordered with respect to the reads of the policy limits in cpufreq_driver_resolve_freq() and in that case, if the limits_changed update in sugov_limits() clobbers the one in sugov_should_update_freq(), the new policy limits may not take effect for a long time. Likewise, the limits_changed update in sugov_limits() may theoretically get reordered with respect to the updates of the policy limits in cpufreq_set_policy() and if sugov_should_update_freq() runs between them, the policy limits change may be missed. To ensure that the above situations will not take place, add memory barriers preventing the reordering in question from taking place and add READ_ONCE() and WRITE_ONCE() annotations around all of the limits_changed flag updates to prevent the compiler from messing up with that code. Fixes: 600f5badb78c ("cpufreq: schedutil: Don't skip freq update when limits change") Cc: 5.3+ # 5.3+ Signed-off-by: Rafael J. Wysocki Reviewed-by: Christian Loehle Link: https://patch.msgid.link/3376719.44csPzL39Z@rjwysocki.net [ bw_min => bw_dl ] Signed-off-by: Sasha Levin --- kernel/sched/cpufreq_schedutil.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 519f742d44f48..954a85b8c2758 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -89,9 +89,20 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) if (!cpufreq_this_cpu_can_update(sg_policy->policy)) return false; - if (unlikely(sg_policy->limits_changed)) { - sg_policy->limits_changed = false; + if (unlikely(READ_ONCE(sg_policy->limits_changed))) { + WRITE_ONCE(sg_policy->limits_changed, false); sg_policy->need_freq_update = true; + + /* + * The above limits_changed update must occur before the reads + * of policy limits in cpufreq_driver_resolve_freq() or a policy + * limits update might be missed, so use a memory barrier to + * ensure it. + * + * This pairs with the write memory barrier in sugov_limits(). + */ + smp_mb(); + return true; } @@ -326,7 +337,7 @@ static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; } static inline void ignore_dl_rate_limit(struct sugov_cpu *sg_cpu) { if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_dl) - sg_cpu->sg_policy->limits_changed = true; + WRITE_ONCE(sg_cpu->sg_policy->limits_changed, true); } static inline bool sugov_update_single_common(struct sugov_cpu *sg_cpu, @@ -826,7 +837,16 @@ static void sugov_limits(struct cpufreq_policy *policy) mutex_unlock(&sg_policy->work_lock); } - sg_policy->limits_changed = true; + /* + * The limits_changed update below must take place before the updates + * of policy limits in cpufreq_set_policy() or a policy limits update + * might be missed, so use a memory barrier to ensure it. + * + * This pairs with the memory barrier in sugov_should_update_freq(). + */ + smp_wmb(); + + WRITE_ONCE(sg_policy->limits_changed, true); } struct cpufreq_governor schedutil_gov = { -- 2.51.0