From nobody Sun Jun 14 20:20:57 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 7F17D2DC789 for ; Mon, 6 Apr 2026 11:01:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775473282; cv=none; b=mEgWZVeFPt6YMqkASr/V/ZvUKlcFKO1kNsSGo5PopUb+IkSKZQX6GzMXl4GSQ4t0psvYnQLsUBAHQAsRUE3Qrm7b740VqqRDACQj+ucfUaE4rpLaSQH4LWmzbKtZPjtT4h1Ja4I/84WCfDdQksSLNXJx18eBs2TgbTb0qu4dIDM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775473282; c=relaxed/simple; bh=1PHBCl6fkaBB6kcX0DfRapCJ2DHs3lNR1Za2ufTgymA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=jFiAosNdlGkN6wBoDg6hzcCDDFC9P1RPYTFDh45GEE36g2WmuOl6sFTKMtuevfshwaQ30fuvP3gGeoNNG0C65Ei/H+XLIlZdcpUZRe9Su6hS3gWBGmRNn4vY7C8ElhvOH1PEzeeb3ZHFeEhyCMyDBwO6szbWgKiOytEw7u/7b+Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=QSMSu8mj; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=IcqF+LKJ; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="QSMSu8mj"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="IcqF+LKJ" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 636A1h4p3484677 for ; Mon, 6 Apr 2026 11:01:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:message-id:mime-version :subject:to; s=qcppdkim1; bh=iFvuZkFHBlbWFKTuJ7rczF/bMXb2VQMAzOP I9N2YllQ=; b=QSMSu8mj7JqZkdrz0FWCyBxB/sMEUwbQvRppyTUdYnaj8lxWlrB lM+Jf+vDKOH0Rk+dELGVDOo/0jHbO2RFEunPD2+cbP3XRI9LgBe3hP1Pi1IB7z3k P0T6c4H1y1xGGgJHQVjdyd0IMyDfENti5uOTXQdsZzITFrX/mfIQ7hweuYui1fVZ jp8yJk0minRIimcDR9GqCVow8EK6S8f2RR2Vsv2EWWvk4+BzhWvacq2JjDSP/6+x EQJd+eOhcg+4aP3iIIGTKIfbuVT2ZjdNcdx7U3Njx4hFarsjaTyxWiorUaNfx7lm Ol47zUPdQMyoM+HWiWzhwFH5HjME9BO/nvg== Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dat7ucwww-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 06 Apr 2026 11:01:20 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2b24e45271cso38182725ad.2 for ; Mon, 06 Apr 2026 04:01:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1775473279; x=1776078079; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=iFvuZkFHBlbWFKTuJ7rczF/bMXb2VQMAzOPI9N2YllQ=; b=IcqF+LKJx8km/UhFamWhUuYGyxivnCgmnz5URn6tb85J6lhXQF7bNd46WgrrmCUoi6 +EG3ZBuOFzW2ZxqKqTZPJEFSc6P/2ydxTHuUiQzjNklKZ/LFvTDZTBgW4f5Whf7mUB8z SwTy3sIGaEgsZfVRs2Q89ikEJ+0/YY52R/JzFMd8/x3Wt5hSCuO5l1nU989oAJtMdcnO 95yCmBRlVvHcw7sqNYWIq0z/kJXTrAEKjIweRPyL6b8oxF/+Jg+Lfz9doMWM+DifiPBJ 3qUpHNJHa/LLoevZ3UFAswAqGOsseef210b4s++fWnYcAWwyCAHabrn9Br3r46IguThG Da5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775473279; x=1776078079; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=iFvuZkFHBlbWFKTuJ7rczF/bMXb2VQMAzOPI9N2YllQ=; b=eucgbAm4FbV2PkeOxLAzYI1l60fUQuVmqQ93lfJ2uoTVuzW+H0Sij2qB2jY/hhHDxs dDglA5hiMQ0ncy0vlpj2yTUlKFKe62DXR7ao+PKfq+x1SiVjlrhK1UQgjG/EuLr2AQ7A wpeAP+Xue6KaYcRlWDw4D7JWg9DM7SLU5Km+aDVhHUe3YnojIN0k2QKOs1n+Dl6s3JfH MPtLIebfntg9CDBvZ0qfOHF1v09H3ixo5pVDqdBTXs4BCtAJp1TN0G6P6IKGE4usIGTx zX8vlFO6ADOsVhLrM2RqYorYAWO+H/fnKRCsUdhep8caiSSn7+PqnQbgGdOXmF7oG1wK XESw== X-Forwarded-Encrypted: i=1; AJvYcCUqNDr8MrUih5VyKU1eF+hWDxg2wajIexov7yvFbWiO7ZDenhQ2oQbzEg0dlJ18GgnU1nj0HmXR8jI0zig=@vger.kernel.org X-Gm-Message-State: AOJu0Ywud4eubLZxndxSKdU/ezBF/0xTXmDu9YPK2b+tcT/OUvlm7l8g E687D/7++KNczA48AucoWNaJHXGQqTt8EP7iMfUWRUZPqtiFyaigBPpjd5uwgf4u3QHA7xLdmxQ bJFXBWEjCzCm/aDXnxPSKWUSiP/3Wc6iskw3lH2loubuWB5Z0dw+uSkwth71SRnTjhDvGjQmEKy Q= X-Gm-Gg: AeBDievloyRl6wazssydZyA5Xo/k23hHrkcjiLxwrS8Z2AnqY7D8cSG32exItdvuInk 32o/u2b8E3bLd1z4CTautGK/B2TZOnnR+EcY53b4HlkeTRpXi8lH+N3Hsv+m21Xxw78D8vQ/v4H wSgiToOOn+RdBtP+q/520nqYnudvqa515e8yCPzFCVRynMJ52uj3cQGvG/ErnaArd+2hmqOBlj6 qQ8EpWS9Sn6Fp8/luQKMPQ0Ur+1HVWCu3OWwo1zsaeemITeVJXgrEtvl2VSWTFGgjw4rpple+Ll t0tq7MLJo8gH67Yv1M83+gklyioNQz+UiKVh9VdSm4o8RkCSoxC7V3oKOmva6v1Rxni45WfjF12 rrechfPLbrhbK+GQ7kpbf6BvV4CghEKUh/Zcl56GszkpvQX2dI59d2zpiKihNoIJT89zGBA2D80 2GEHIeguDaL35K X-Received: by 2002:a17:903:2c05:b0:2a9:e8b:5326 with SMTP id d9443c01a7336-2b28183277emr138123085ad.23.1775473279018; Mon, 06 Apr 2026 04:01:19 -0700 (PDT) X-Received: by 2002:a17:903:2c05:b0:2a9:e8b:5326 with SMTP id d9443c01a7336-2b28183277emr138122515ad.23.1775473278426; Mon, 06 Apr 2026 04:01:18 -0700 (PDT) Received: from zhonhan-gv.qualcomm.com (tpe-colo-wan-fw-bordernet.qualcomm.com. [103.229.16.4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b27472d20bsm136503625ad.16.2026.04.06.04.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 04:01:17 -0700 (PDT) From: Zhongqiu Han To: rafael@kernel.org, viresh.kumar@linaro.org Cc: venkatesh.pallipadi@intel.com, davej@redhat.com, trenn@suse.de, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, zhongqiu.han@oss.qualcomm.com Subject: [PATCH] cpufreq: governor: Fix race between sysfs store and dbs work handler Date: Mon, 6 Apr 2026 19:01:13 +0800 Message-ID: <20260406110113.3475920-1-zhongqiu.han@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDA2MDEwOCBTYWx0ZWRfXzhg0jxRBI2n1 CdoM55b2hTOVVZuOOO4SRjKJ9kmf1ODXxFdFk1gEhhN2b2HDeB56UXGC1psYans0B47i+GD4Psh LCYHeRMDqv5TJ7sYJnV2IyYSZGUbwuHQWud3TfMstXk0u9kcqdWHpq60KYr4au5wOwKHnJIXGRo sK3a5z7O5QfhZp/PXmc7NTOMUrWb6jV198jjoiKZJWHf5Sk2z7hT/j8BA8CLxOs/PhsX7WnG+r1 iiGYf77VEAPjDBvLao+blJHgILWJy+y5GqlZKnWrFh8uAD/Lh4wVdsUDL2pqQr0APyvggkNTjoN 7Yl3uXy9es++IA3yHZfgBMOQNndVaeXqIfNKbaRgjWIBZzgw+zrteI3zv2mZKUMUL+2thmM0O/d JSFAnb149//HrHnd87BQXHEWUfSP6FP2BJuQQYNyIw2mWNHkHPxhMIYrCpZHQH88uZkxQBDleoP Vy2ijc5aZancqID0dJA== X-Proofpoint-GUID: AIZ65fkaH_TgH8B5BaquQI_Kx6mEtYzT X-Authority-Analysis: v=2.4 cv=RJ2+3oi+ c=1 sm=1 tr=0 ts=69d39280 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=nuhDOHQX5FNHPW3J6Bj6AA==:17 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=Xzaa9a87-0lj3eSA-_AA:9 a=1OuFwYUASf3TG4hYMiVC:22 X-Proofpoint-ORIG-GUID: AIZ65fkaH_TgH8B5BaquQI_Kx6mEtYzT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-06_02,2026-04-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 lowpriorityscore=0 malwarescore=0 impostorscore=0 adultscore=0 clxscore=1015 spamscore=0 phishscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2603050001 definitions=main-2604060108 Content-Type: text/plain; charset="utf-8" gov_update_cpu_data() resets per-CPU prev_cpu_idle and prev_cpu_nice for every CPU in the governed domain. It is called from sysfs store callbacks (e.g. ignore_nice_load_store) which run under attr_set->update_lock, held by the surrounding governor_store(). Concurrently, dbs_work_handler() calls gov->gov_dbs_update() (which calls dbs_update()) under policy_dbs->update_mutex. dbs_update() both reads and writes the same prev_cpu_idle / prev_cpu_nice fields. The potential race path is: Path A (sysfs write, holds attr_set->update_lock only): governor_store() mutex_lock(&attr_set->update_lock) ignore_nice_load_store() dbs_data->ignore_nice_load =3D input gov_update_cpu_data(dbs_data) list_for_each_entry(policy_dbs, ...) for_each_cpu(j, ...) j_cdbs->prev_cpu_idle =3D get_cpu_idle_time(...) /* write */ j_cdbs->prev_cpu_nice =3D kcpustat_field(...) /* write */ mutex_unlock(&attr_set->update_lock) Path B (work queue, holds policy_dbs->update_mutex only): dbs_work_handler() mutex_lock(&policy_dbs->update_mutex) gov->gov_dbs_update(policy) dbs_update() for_each_cpu(j, policy->cpus) idle_time =3D cur - j_cdbs->prev_cpu_idle /* read */ j_cdbs->prev_cpu_idle =3D cur_idle_time /* write */ idle_time +=3D cur_nice - j_cdbs->prev_cpu_nice /* read */ j_cdbs->prev_cpu_nice =3D cur_nice /* write */ mutex_unlock(&policy_dbs->update_mutex) Because attr_set->update_lock and policy_dbs->update_mutex are two completely independent locks, the two paths are not mutually exclusive. This results in a data race on cpu_dbs_info.prev_cpu_idle and cpu_dbs_info.prev_cpu_nice. Fix this by also acquiring policy_dbs->update_mutex in gov_update_cpu_data() for each policy, so that path A participates in the mutual exclusion already established by dbs_work_handler(). Also update the function comment to accurately reflect the two-level locking contract. The root of this race dates back to the original ondemand/conservative governors. Before commit ee88415caf73 ("[CPUFREQ] Cleanup locking in conservative governor") and commit 5a75c82828e7 ("[CPUFREQ] Cleanup locking in ondemand governor"), all accesses to prev_cpu_idle and prev_cpu_nice in cpufreq_governor_dbs() (path X), store_ignore_nice_load() (path Y), and do_dbs_timer() (path Z) were serialised by the same dbs_mutex, so no race existed. Those two commits switched do_dbs_timer() from dbs_mutex to a per-policy/per-cpu timer_mutex to reduce lock contention, but left store_ignore_nice_load() still holding dbs_mutex. As a result, path Y (store) and path Z (do_dbs_timer) no longer shared a common lock, introducing a potential race on prev_cpu_idle/prev_cpu_nice between store_ignore_nice_load() and dbs_check_cpu(). Commit 326c86deaed54a ("[CPUFREQ] Remove unneeded locks") then removed dbs_mutex from store_ignore_nice_load() entirely, introducing an additional potential race between store_ignore_nice_load() (path Y, now lockless) and cpufreq_governor_dbs() (path X, still holding dbs_mutex), while the race between path Y and path Z remained. Fixes: ee88415caf736b ("[CPUFREQ] Cleanup locking in conservative governor") Fixes: 5a75c82828e7c0 ("[CPUFREQ] Cleanup locking in ondemand governor") Fixes: 326c86deaed54a ("[CPUFREQ] Remove unneeded locks") Signed-off-by: Zhongqiu Han --- drivers/cpufreq/cpufreq_governor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_g= overnor.c index 86f35e451914..56ef793362db 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -90,7 +90,8 @@ EXPORT_SYMBOL_GPL(sampling_rate_store); * (that may be a single policy or a bunch of them if governor tunables are * system-wide). * - * Call under the @dbs_data mutex. + * Call under the @dbs_data->attr_set.update_lock. The per-policy + * update_mutex is acquired and released internally for each policy. */ void gov_update_cpu_data(struct dbs_data *dbs_data) { @@ -99,6 +100,7 @@ void gov_update_cpu_data(struct dbs_data *dbs_data) list_for_each_entry(policy_dbs, &dbs_data->attr_set.policy_list, list) { unsigned int j; =20 + mutex_lock(&policy_dbs->update_mutex); for_each_cpu(j, policy_dbs->policy->cpus) { struct cpu_dbs_info *j_cdbs =3D &per_cpu(cpu_dbs, j); =20 @@ -107,6 +109,7 @@ void gov_update_cpu_data(struct dbs_data *dbs_data) if (dbs_data->ignore_nice_load) j_cdbs->prev_cpu_nice =3D kcpustat_field(&kcpustat_cpu(j), CPUTIME_NIC= E, j); } + mutex_unlock(&policy_dbs->update_mutex); } } EXPORT_SYMBOL_GPL(gov_update_cpu_data); --=20 2.43.0