From nobody Wed Apr 1 12:32:53 2026 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35C762561A7 for ; Tue, 31 Mar 2026 05:04:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774933445; cv=none; b=g3iE3KRZ5GR8EbaxM7hknd0A+UbwjrovzsvCWQT9eZ4Q+c4e25VJE5BlrjJIGwxPtRu3XODIuVG6cKLlM3kxROn6yGlsSHF0sEy9lv8Mc75LZCkS8I9BH6U48UijjBfFy9Uyy39A6HDFkyvQDsz+EDs/6DVffx+/Chs7DtOBOcM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774933445; c=relaxed/simple; bh=1NSh/swu976NVuzV/HSvczmTa6ufvUbJP4waEsEU9QM=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=ibm+YL6OtA55VPMR9gmXfmTIuAWWFSL+Bm8OmbaJ4YREveLVrPeZap8QYHFjWHUHEHAZ7/MSdUvOqk+jPjjlPINpkH8dRwsOu7Nkc+RqnMo5k/6lsGthaw4d4nZszAqklirm63var7xZcwtcM6621xDzGYMvPFaagxsgSmWokQQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=UsAjKl5o; arc=none smtp.client-ip=209.85.216.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="UsAjKl5o" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-35da2d35eccso1336697a91.0 for ; Mon, 30 Mar 2026 22:04:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1774933441; x=1775538241; 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=EThWSHxuvmimBlMnRXeRebZZ8M9RIPcyPhmfVOOBqeE=; b=UsAjKl5oP/gXrf2b53D8GTLJuoqwpvKHIdo6hmHW7uZEk+6u1UZh4jn6dVjKdT923Q oR1HS97riR5JWrzbSEuZn9fHEtI1r8SLp01kyvR9zbBB2OkJhdmFlDsusB2EBBGrzpZd jBzfrPK2/CN+FvSWtDoANm03T6w7l7gNpa2M3jJDmT9pjMikGJMYys8mJ1v1TyfP/SJn v2bOCzoDg1zgxc3wDsrULv/xMD/es2p2MAnuheDo/mFCntE4NLsIeoRABIfPIwgf0yPt bjN9HYnYVqmoOG/BnHNPWL+9Vgx2TMDytAXhLuRnVwzZFh1EzhAEd9bmsgo8Uws3RkRB ogSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774933441; x=1775538241; 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=EThWSHxuvmimBlMnRXeRebZZ8M9RIPcyPhmfVOOBqeE=; b=mI6ICjt9OXAU3tHS7f63yd8Gp22qKchdYVEV+a+7BS2G38SDjQ4QdVgcgM7PYyl0xg RzhektJAQms4eNEZLg/bNG2D6KkEuWkgUxT5M8OS7ZegLmtpl0trxQj7Ew6T5SGqIta4 MD8+LNxwglrYHYG2JTwMeLZp0fgXnOkyTmHQbVXd0N9oN2/3ub/Ef9Wk7ZidfSwJhoIU rAtuKWGSF0+zsjPfF49WF81l87Ksm+rWSJzZz0Pc6YpuOXCD+2JmL+o7QNc4tX79nROy X3XPxrKiJMtZfxOlgZi9svaYgcJpw3rQEhpjxMygTghQYBK+zDKij82nE072Riy0hU/N zDKw== X-Forwarded-Encrypted: i=1; AJvYcCVRoLtni7wgjojGvntfG0xSY1JXochfUC/oBPOZWb07VbXBITjPbbZobyWGbm7ZvEwzHZVMl8KD3epEGw4=@vger.kernel.org X-Gm-Message-State: AOJu0YzLj7oPtVRnFmjCIt/+4wzFkZ7XdLcOdTlk50GaB00/KM4Twftp 5ammWDAc2lRcJ8VFWPpBrM8Ehod30ury/0s98M9v+eS1v1oSrKTz9LBMIXKT6aWdR2f+hjPWAdU 3AmDL X-Gm-Gg: ATEYQzxXc5NMNWSikkAvTIK7TiiK2bGhs0dM5jZ5Jrq9N5UJ3RsR8MdBSTYkY9D2n+q hSN4SqEkR7zCy3giCbxHHeTPa8Wzd/C0n7DOYLk3mGX/8Zw23cVv5qf+UGa3CJ12gbqcLtTj9Hi HwjHSV7dGJHgmM6fpPv3bG0ktlgEt5vC09BtXaR6BK3xHOFflD0+CAtlPmbu0hxTY1FARsfufCw zfhb/EchFNV4uM1ZwpkPOHxP/EJmKW4+jyIv9vf9Q9YZLhnW1NZuNsuNb805qD4HRkkXh8074WN iwYN4h8L4OyhdV0NmBXWaUlanbgMk2g1QrWSddrXveGX+7mOzdk/JtN8f+QFru3NjFA5EgS9o1R 3TuLK4sTN4tIzho7YA7i9SE80H8yuGgQjLI9oZ2n77ZHe3rTOOcsN2PJud2eFC9k6RG8Pg1rm+x bEdcCms/JKZ9TNjgHQtkAX62g2 X-Received: by 2002:a17:90b:4d0d:b0:35d:a542:2dbf with SMTP id 98e67ed59e1d1-35da5423441mr5772668a91.20.1774933441300; Mon, 30 Mar 2026 22:04:01 -0700 (PDT) Received: from localhost ([122.172.81.200]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35dba33bfb9sm364425a91.0.2026.03.30.22.04.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 22:04:00 -0700 (PDT) From: Viresh Kumar To: "Rafael J. Wysocki" , Viresh Kumar , Pierre Gondois , Lifeng Zheng Cc: linux-pm@vger.kernel.org, Vincent Guittot , Sumit Semwal , Zhongqiu Han , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH] cpufreq: Allocate QoS freq_req objects with policy Date: Tue, 31 Mar 2026 10:33:46 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 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 Content-Type: text/plain; charset="utf-8" A recent change exposed a bug in the error path: if freq_qos_add_request(boost_freq_req) fails, min_freq_req may remain a valid pointer even though it was never successfully added. During policy teardown, this leads to an unconditional call to freq_qos_remove_request(), triggering a WARN. The current design allocates all three freq_req objects together, making the lifetime rules unclear and error handling fragile. Simplify this by allocating the QoS freq_req objects at policy allocation time. The policy itself is dynamically allocated, and two of the three requests are always needed anyway. This ensures consistent lifetime management and eliminates the inconsistent state in failure paths. Reported-by: Zhongqiu Han Fixes: 6e39ba4e5a82 ("cpufreq: Add boost_freq_req QoS request") Signed-off-by: Viresh Kumar Reviewed-by: Lifeng Zheng Reviewed-by: Zhongqiu Han Tested-by: Pierre Gondois --- drivers/cpufreq/cpufreq.c | 53 +++++++++++---------------------------- include/linux/cpufreq.h | 6 ++--- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c0aa970c7a67..f4a949f1e48f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -614,7 +614,7 @@ static int policy_set_boost(struct cpufreq_policy *poli= cy, bool enable) return ret; } =20 - ret =3D freq_qos_update_request(policy->boost_freq_req, policy->cpuinfo.m= ax_freq); + ret =3D freq_qos_update_request(&policy->boost_freq_req, policy->cpuinfo.= max_freq); if (ret < 0) { policy->boost_enabled =3D !policy->boost_enabled; cpufreq_driver->set_boost(policy, policy->boost_enabled); @@ -769,7 +769,7 @@ static ssize_t store_##file_name \ if (ret) \ return ret; \ \ - ret =3D freq_qos_update_request(policy->object##_freq_req, val);\ + ret =3D freq_qos_update_request(&policy->object##_freq_req, val); \ return ret >=3D 0 ? count : ret; \ } =20 @@ -1374,7 +1374,7 @@ static void cpufreq_policy_free(struct cpufreq_policy= *policy) /* Cancel any pending policy->update work before freeing the policy. */ cancel_work_sync(&policy->update); =20 - if (policy->max_freq_req) { + if (freq_qos_request_active(&policy->max_freq_req)) { /* * Remove max_freq_req after sending CPUFREQ_REMOVE_POLICY * notification, since CPUFREQ_CREATE_POLICY notification was @@ -1382,12 +1382,13 @@ static void cpufreq_policy_free(struct cpufreq_poli= cy *policy) */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_REMOVE_POLICY, policy); - freq_qos_remove_request(policy->max_freq_req); + freq_qos_remove_request(&policy->max_freq_req); } =20 - freq_qos_remove_request(policy->min_freq_req); - freq_qos_remove_request(policy->boost_freq_req); - kfree(policy->min_freq_req); + if (freq_qos_request_active(&policy->min_freq_req)) + freq_qos_remove_request(&policy->min_freq_req); + if (freq_qos_request_active(&policy->boost_freq_req)) + freq_qos_remove_request(&policy->boost_freq_req); =20 cpufreq_policy_put_kobj(policy); free_cpumask_var(policy->real_cpus); @@ -1452,57 +1453,31 @@ static int cpufreq_policy_online(struct cpufreq_pol= icy *policy, cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); =20 if (new_policy) { - unsigned int count; - for_each_cpu(j, policy->related_cpus) { per_cpu(cpufreq_cpu_data, j) =3D policy; add_cpu_dev_symlink(policy, j, get_cpu_device(j)); } =20 - count =3D policy->boost_supported ? 3 : 2; - policy->min_freq_req =3D kzalloc(count * sizeof(*policy->min_freq_req), - GFP_KERNEL); - if (!policy->min_freq_req) { - ret =3D -ENOMEM; - goto out_destroy_policy; - } - if (policy->boost_supported) { - policy->boost_freq_req =3D policy->min_freq_req + 2; - ret =3D freq_qos_add_request(&policy->constraints, - policy->boost_freq_req, + &policy->boost_freq_req, FREQ_QOS_MAX, policy->cpuinfo.max_freq); - if (ret < 0) { - policy->boost_freq_req =3D NULL; + if (ret < 0) goto out_destroy_policy; - } } =20 ret =3D freq_qos_add_request(&policy->constraints, - policy->min_freq_req, FREQ_QOS_MIN, + &policy->min_freq_req, FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); - if (ret < 0) { - kfree(policy->min_freq_req); - policy->min_freq_req =3D NULL; + if (ret < 0) goto out_destroy_policy; - } - - /* - * This must be initialized right here to avoid calling - * freq_qos_remove_request() on uninitialized request in case - * of errors. - */ - policy->max_freq_req =3D policy->min_freq_req + 1; =20 ret =3D freq_qos_add_request(&policy->constraints, - policy->max_freq_req, FREQ_QOS_MAX, + &policy->max_freq_req, FREQ_QOS_MAX, FREQ_QOS_MAX_DEFAULT_VALUE); - if (ret < 0) { - policy->max_freq_req =3D NULL; + if (ret < 0) goto out_destroy_policy; - } =20 blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_CREATE_POLICY, policy); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index b6f6c7d06912..9b10eb486ece 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -79,9 +79,9 @@ struct cpufreq_policy { * called, but you're in IRQ context */ =20 struct freq_constraints constraints; - struct freq_qos_request *min_freq_req; - struct freq_qos_request *max_freq_req; - struct freq_qos_request *boost_freq_req; + struct freq_qos_request min_freq_req; + struct freq_qos_request max_freq_req; + struct freq_qos_request boost_freq_req; =20 struct cpufreq_frequency_table *freq_table; enum cpufreq_table_sorting freq_table_sorted; --=20 2.31.1.272.g89b43f80a514