From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 210142C11D6; Wed, 25 Feb 2026 08:49:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009394; cv=none; b=keF8bucdMtkVTqsOcS8RqXjl1xt3UIqoW7Ldji3qjTYloSj6RvJveT6GV3fOOEa+Az7lVnRUyyc7Q5bruEKAd0YLbARYAPRr3UUYimtKmtcid78jloxk9rMECfJl5HKSnDUFySmr/JUCPt3SlDM4NSvIW04R9Som6b4iY6pqpQM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009394; c=relaxed/simple; bh=0XuRh2d/myguiCEUP5T6yX1ZmrbAbjyTCrGGdy3n8YA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sMjK1Z1xsRRNVaOOehM9jY1ueASlviPsykMoeM/Yp/fcnhx6u0YNGdWb6Kww0XRxhnAme5xaQbZiZUWiPoWWlKBjiO2dK5ExbdQLB3T+/f4ExzvyQGOUH1PezV/E4P9Vxk5KFYCg+af5XGOlhtxbcdEu/t/pbnSDPx5BfUQ7A74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 51B531691; Wed, 25 Feb 2026 00:49:46 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 196543F59E; Wed, 25 Feb 2026 00:49:48 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [PATCH v5 1/6] cpufreq: Remove per-CPU QoS constraint Date: Wed, 25 Feb 2026 09:49:18 +0100 Message-ID: <20260225084930.1692228-2-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" policy->max_freq_req represents the maximum allowed frequency as requested by the policyX/scaling_max_freq sysfs file. This request applies to all CPUs of the policy. It is not possible to request a per-CPU maximum frequency. Thus, the interaction between the policy boost and scaling_max_freq settings should be handled by adding a boost specific QoS constraint. This will be handled in the following patches. This patch reverts of: commit 1608f0230510 ("cpufreq: Fix re-boost issue after hotplugging a CPU") Reviewed-by: Lifeng Zheng Signed-off-by: Pierre Gondois --- drivers/cpufreq/cpufreq.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4472bb1ec83c7..db414c052658b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1481,10 +1481,6 @@ static int cpufreq_policy_online(struct cpufreq_poli= cy *policy, =20 blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_CREATE_POLICY, policy); - } else { - ret =3D freq_qos_update_request(policy->max_freq_req, policy->max); - if (ret < 0) - goto out_destroy_policy; } =20 if (cpufreq_driver->get && has_target()) { --=20 2.43.0 From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 83EED2FCBF0; Wed, 25 Feb 2026 08:49:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009398; cv=none; b=kHxwSort1hf6HYpq6A5+TIZ4eqlg87YtjR0aaSNoF7iZrs/S6MfRz2wTPlp0yd4wnq6Yq5qxTnH7xUAcW78AcfieLv2CiXOpghnhERc3eowiLRSPrzf3khVV49rkDgvmqCij/+KGMqrZ99G2YbXocFffBc5/vE48XcZLcLy2Mnk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009398; c=relaxed/simple; bh=t0CSvy2V1vN07Nv5rVFVH6JCFFQHEcv+rViGBGNGM/c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kAwI1eqFvtnBpptg0O6kdn5k0FpGV74UxVwl7c+0JMMte9afL6Qpkt+cUXdCMKUbjhgwxUfMTK6V3JOEzVEZOKrG0Y1ZEhEyxIu5lH7h5HUEiVVgOQ16wqbyoKJPkkjK8Rt1Wfp3echXzTAmMr8WMPcPVm0SQCV0cEjtHsOn3Rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C666F165C; Wed, 25 Feb 2026 00:49:50 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C4FC93F59E; Wed, 25 Feb 2026 00:49:53 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [PATCH v5 2/6] cpufreq: Add boost_freq_req QoS request Date: Wed, 25 Feb 2026 09:49:19 +0100 Message-ID: <20260225084930.1692228-3-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" The Power Management Quality of Service (PM QoS) allows to aggregate constraints from multiple entities. It is currently used to manage the min/max frequency of a given policy. Frequency constraints can come for instance from: - Thermal framework: acpi_thermal_cpufreq_init() - Firmware: _PPC objects: acpi_processor_ppc_init() - User: by setting policyX/scaling_[min|max]_freq The minimum of the max frequency constraints is used to compute the resulting maximum allowed frequency. When enabling boost frequencies, the same frequency request object (policy->max_freq_req) as to handle requests from users is used. As a result, when setting: - scaling_max_freq - boost The last sysfs file used overwrites the request from the other sysfs file. To avoid this, create a per-policy boost_freq_req to save the boost constraints instead of overwriting the last scaling_max_freq constraint. Signed-off-by: Pierre Gondois --- drivers/cpufreq/cpufreq.c | 37 ++++++++++++++++++++++++++++++++----- include/linux/cpufreq.h | 1 + 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index db414c052658b..50467b938668a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1359,17 +1359,21 @@ static void cpufreq_policy_free(struct cpufreq_poli= cy *policy) /* Cancel any pending policy->update work before freeing the policy. */ cancel_work_sync(&policy->update); =20 - if (policy->max_freq_req) { + if ((policy->max_freq_req && !policy->boost_supported) || + policy->boost_freq_req) { /* - * Remove max_freq_req after sending CPUFREQ_REMOVE_POLICY - * notification, since CPUFREQ_CREATE_POLICY notification was - * sent after adding max_freq_req earlier. + * Remove max/boost _freq_req after sending CPUFREQ_REMOVE_POLICY + * notification, since CPUFREQ_CREATE_POLICY notification was sent + * after adding max/boost _freq_req earlier. */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_REMOVE_POLICY, policy); - freq_qos_remove_request(policy->max_freq_req); } =20 + freq_qos_remove_request(policy->boost_freq_req); + kfree(policy->boost_freq_req); + + freq_qos_remove_request(policy->max_freq_req); freq_qos_remove_request(policy->min_freq_req); kfree(policy->min_freq_req); =20 @@ -1479,6 +1483,29 @@ static int cpufreq_policy_online(struct cpufreq_poli= cy *policy, goto out_destroy_policy; } =20 + if (policy->boost_supported) { + policy->boost_freq_req =3D kzalloc(sizeof(*policy->boost_freq_req), + GFP_KERNEL); + if (!policy->boost_freq_req) { + ret =3D -ENOMEM; + goto out_destroy_policy; + } + + ret =3D freq_qos_add_request(&policy->constraints, + policy->boost_freq_req, + FREQ_QOS_MAX, + FREQ_QOS_MAX_DEFAULT_VALUE); + if (ret < 0) { + /* + * So we don't call freq_qos_remove_request() for an + * uninitialized request. + */ + kfree(policy->boost_freq_req); + policy->boost_freq_req =3D NULL; + goto out_destroy_policy; + } + } + 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 0465d1e6f72ac..c292a6a19e4f5 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -81,6 +81,7 @@ struct cpufreq_policy { 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; =20 struct cpufreq_frequency_table *freq_table; enum cpufreq_table_sorting freq_table_sorted; --=20 2.43.0 From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B15943115BD; Wed, 25 Feb 2026 08:50:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009403; cv=none; b=dU0dcTCzxyy6UDsQ06/L6LNwEP0v+E965CeP+8YKkEUsGC7gUhMfCZecn8qwaGVwkX4KpF9JDVJRJDDE0zibxkPATkO54DaXxxCHQEKhap7I7JkTcqqYmY4UdKaNijMWs9wd1y8plL97PJH9xxqkzk5j6xLs5ukzyq9PmcpiLo4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009403; c=relaxed/simple; bh=WBZ8irYDkD+ZH3PFhsp9vgFr2ImxtrjhxlO9Fx2Li8U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nfRE33EN5Z7RSrLNcz8tsnajFAymsTy0aV9nV4bYpEkdyOpwibaN9v+vh6g98Msv1hFjTPmqm+pg+nJR5lsHlcvwgTS/IeP2PDRfSYVaIQr+LwcmahYqaCFg6JlaRqc1BuakZph9nJk88HV3BWcpQEO6FLFIPZ+Nk1ZLkNTqE54= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 807C3165C; Wed, 25 Feb 2026 00:49:55 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 652333F59E; Wed, 25 Feb 2026 00:49:58 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [PATCH v5 3/6] cpufreq: Centralize boost freq QoS requests Date: Wed, 25 Feb 2026 09:49:20 +0100 Message-ID: <20260225084930.1692228-4-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" policy_set_boost() calls the cpufreq set_boost callback. Update the newly added boost_freq_req request from there: - whenever boost is toggled - to cover all possible paths Signed-off-by: Pierre Gondois --- drivers/cpufreq/cpufreq.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 50467b938668a..42de32488f422 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -603,10 +603,19 @@ static int policy_set_boost(struct cpufreq_policy *po= licy, bool enable) policy->boost_enabled =3D enable; =20 ret =3D cpufreq_driver->set_boost(policy, enable); - if (ret) + if (ret) { policy->boost_enabled =3D !policy->boost_enabled; + return ret; + } =20 - return ret; + ret =3D freq_qos_update_request(policy->boost_freq_req, policy->cpuinfo.m= ax_freq); + if (ret < 0) { + policy->boost_enabled =3D !policy->boost_enabled; + cpufreq_driver->set_boost(policy, policy->boost_enabled); + return ret; + } + + return 0; } =20 static ssize_t store_local_boost(struct cpufreq_policy *policy, --=20 2.43.0 From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F083F31159C; Wed, 25 Feb 2026 08:50:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009408; cv=none; b=R6S+bwEnGMi3jiQCaLZjkRgyLCUlCc+QIXO/TLZDcFHV4Q9vvewpnq67IK+G9mbNoiH+W6Z4OZlP+yTWAdv8OKv4+FmNkP04i+HTOuy+Gwl+6hUKefhmrgYgvP7l+DwWGaVKmSPAtamEIiKOaL+FHPxQWFc5oe9RYPQBd61RdT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009408; c=relaxed/simple; bh=5h/KzbDoPmUb02rODNvzgGXvVjv/K+uw/125oBtaZnY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nz7L7Db+5Ap4cnC8eJqOGuymdktoTAsDisDK4CyMs7pPIQVBy+UxxrRlR8B9XcyumIMEt+MbaMfDHFZY95akG+AFPOObKqFImPOcfEkNiu2sroVEZ/5IML3TaSA2H44kzM1G5QJWvdoj6jFt8F7AsCR0DTmH1k3BuJ58m0xhAlk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 31139169E; Wed, 25 Feb 2026 00:50:00 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F17CE3F59E; Wed, 25 Feb 2026 00:50:02 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [PATCH v5 4/6] cpufreq: Update .set_boost() callbacks to rely on boost_freq_req Date: Wed, 25 Feb 2026 09:49:21 +0100 Message-ID: <20260225084930.1692228-5-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" In the existing .set_boost() callbacks: - Don't update policy->max as this is done through the qos notifier cpufreq_notifier_max() which calls cpufreq_set_policy(). - Remove freq_qos_update_request() calls as the qos request is now done in policy_set_boost() and updates the new boost_freq_req Note: cpufreq_frequency_table_cpuinfo() is also called through: cpufreq_policy_online() \-cpufreq_table_validate_and_sort() \-cpufreq_frequency_table_cpuinfo() which relies on cpufreq_frequency_table_cpuinfo() to set policy->min and max initizalization at driver init. This regression is solved in the next patch. Note2: acpi-cpufreq.c seems to be the only cpufreq driver not setting cpuinfo.max_freq. Populate it the nominal frequency at driver init. Signed-off-by: Pierre Gondois --- drivers/cpufreq/acpi-cpufreq.c | 1 + drivers/cpufreq/amd-pstate.c | 2 -- drivers/cpufreq/cppc_cpufreq.c | 10 ++-------- drivers/cpufreq/cpufreq.c | 16 +++++++--------- drivers/cpufreq/freq_table.c | 7 +++---- 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index e73a66785d69d..6a6e26e1be14a 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -857,6 +857,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy = *policy) * governor from selecting inadequate CPU frequencies. */ arch_set_max_freq_ratio(true); + policy->cpuinfo.max_freq =3D nominal_freq; } =20 policy->freq_table =3D freq_table; diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index c45bc98721d24..310d5938cbdf6 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -756,8 +756,6 @@ static int amd_pstate_cpu_boost_update(struct cpufreq_p= olicy *policy, bool on) else if (policy->cpuinfo.max_freq > nominal_freq) policy->cpuinfo.max_freq =3D nominal_freq; =20 - policy->max =3D policy->cpuinfo.max_freq; - if (cppc_state =3D=3D AMD_PSTATE_PASSIVE) { ret =3D freq_qos_update_request(&cpudata->req[1], policy->cpuinfo.max_fr= eq); if (ret < 0) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 9eac77c4f2944..4c46c7ea318eb 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -775,17 +775,11 @@ static int cppc_cpufreq_set_boost(struct cpufreq_poli= cy *policy, int state) { struct cppc_cpudata *cpu_data =3D policy->driver_data; struct cppc_perf_caps *caps =3D &cpu_data->perf_caps; - int ret; =20 if (state) - policy->max =3D cppc_perf_to_khz(caps, caps->highest_perf); + policy->cpuinfo.max_freq =3D cppc_perf_to_khz(caps, caps->highest_perf); else - policy->max =3D cppc_perf_to_khz(caps, caps->nominal_perf); - policy->cpuinfo.max_freq =3D policy->max; - - ret =3D freq_qos_update_request(policy->max_freq_req, policy->max); - if (ret < 0) - return ret; + policy->cpuinfo.max_freq =3D cppc_perf_to_khz(caps, caps->nominal_perf); =20 return 0; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 42de32488f422..20266fb42d18d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1500,10 +1500,14 @@ static int cpufreq_policy_online(struct cpufreq_pol= icy *policy, goto out_destroy_policy; } =20 + /* + * If boost is supported, + * init the constraint with cpuinfo.max_freq. + */ ret =3D freq_qos_add_request(&policy->constraints, policy->boost_freq_req, FREQ_QOS_MAX, - FREQ_QOS_MAX_DEFAULT_VALUE); + policy->cpuinfo.max_freq); if (ret < 0) { /* * So we don't call freq_qos_remove_request() for an @@ -2818,16 +2822,10 @@ int cpufreq_boost_set_sw(struct cpufreq_policy *pol= icy, int state) return -ENXIO; =20 ret =3D cpufreq_frequency_table_cpuinfo(policy); - if (ret) { + if (ret) pr_err("%s: Policy frequency update failed\n", __func__); - return ret; - } =20 - ret =3D freq_qos_update_request(policy->max_freq_req, policy->max); - if (ret < 0) - return ret; - - return 0; + return ret; } EXPORT_SYMBOL_GPL(cpufreq_boost_set_sw); =20 diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 7f251daf03ce3..9b37f37c36389 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -49,16 +49,15 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_poli= cy *policy) max_freq =3D freq; } =20 - policy->min =3D policy->cpuinfo.min_freq =3D min_freq; - policy->max =3D max_freq; + policy->cpuinfo.min_freq =3D min_freq; /* * If the driver has set its own cpuinfo.max_freq above max_freq, leave * it as is. */ if (policy->cpuinfo.max_freq < max_freq) - policy->max =3D policy->cpuinfo.max_freq =3D max_freq; + policy->cpuinfo.max_freq =3D max_freq; =20 - if (policy->min =3D=3D ~0) + if (min_freq =3D=3D ~0) return -EINVAL; else return 0; --=20 2.43.0 From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4F8FF31BC84; Wed, 25 Feb 2026 08:50:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009413; cv=none; b=ZeCqDNBDC35xRDBJpywlhrsDP/9xNRJ+tZxQnWeL7HYHlDIswwkMa0xBcNZP71JNCBOfCKzt0+KwRLvXVHK3/PBmaYoejw6IOOcZbriaK8enj2hsGwRUc8IKnapdc8DLkx3IOwN3rlcWtT77ZdXQ/6uHwKV4m3U6VKJ3OHaejxw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009413; c=relaxed/simple; bh=MKQACiCZQMjjR9QQVYbI6dzrK1qW3q4y9pX609FIPD8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F93lMQHsedtAi+U99wJcb5GH2KUAlv8ioe716fho0WEESd1TCSUrUIhXCiITuQ6hyMHGVfrFg3XS2wAek51QolyzvRpo5bhm/ToXNBepIWdwT8MGRc3ZZgIzJZ0hep/TC5Me4qqjKXYA8eb18uePsf+8/crxN0W28GLLvBjP41k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7CD2B165C; Wed, 25 Feb 2026 00:50:04 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id A4F773F59E; Wed, 25 Feb 2026 00:50:07 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [PATCH v5 5/6] cpufreq: Set policy->min and max as real QoS constraints Date: Wed, 25 Feb 2026 09:49:22 +0100 Message-ID: <20260225084930.1692228-6-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" cpufreq_set_policy() will ultimately override the policy min/max values written in the .init() callback through: cpufreq_policy_online() \-cpufreq_init_policy() \-cpufreq_set_policy() \-/* Set policy->min/max */ Thus the policy min/max values provided are only temporary. There is an exception if CPUFREQ_NEED_INITIAL_FREQ_CHECK is set and: cpufreq_policy_online() \-cpufreq_init_policy() \-__cpufreq_driver_target() \-cpufreq_driver->target() is called. In this case, some drivers use the policy min/max values in their .target() callback before they are overridden. Check cpufreq drivers: - if their .target() callback doesn't use policy->min or max, remove the initialization - assuming policy->min or max values were populated as constraints, set them as QoS real constraints in cpufreq_policy_online() Signed-off-by: Pierre Gondois --- drivers/cpufreq/amd-pstate.c | 24 ++++++++++++------------ drivers/cpufreq/cpufreq-nforce2.c | 4 ++-- drivers/cpufreq/cpufreq.c | 16 ++++++++++++++-- drivers/cpufreq/gx-suspmod.c | 9 ++++----- drivers/cpufreq/intel_pstate.c | 3 --- drivers/cpufreq/pcc-cpufreq.c | 8 ++++---- drivers/cpufreq/pxa3xx-cpufreq.c | 4 ++-- drivers/cpufreq/virtual-cpufreq.c | 5 +---- 8 files changed, 39 insertions(+), 34 deletions(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 310d5938cbdf6..aaafbe9b26cae 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1003,12 +1003,12 @@ static int amd_pstate_cpu_init(struct cpufreq_polic= y *policy) =20 perf =3D READ_ONCE(cpudata->perf); =20 - policy->cpuinfo.min_freq =3D policy->min =3D perf_to_freq(perf, - cpudata->nominal_freq, - perf.lowest_perf); - policy->cpuinfo.max_freq =3D policy->max =3D perf_to_freq(perf, - cpudata->nominal_freq, - perf.highest_perf); + policy->cpuinfo.min_freq =3D perf_to_freq(perf, + cpudata->nominal_freq, + perf.lowest_perf); + policy->cpuinfo.max_freq =3D perf_to_freq(perf, + cpudata->nominal_freq, + perf.highest_perf); =20 ret =3D amd_pstate_cppc_enable(policy); if (ret) @@ -1485,12 +1485,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_p= olicy *policy) =20 perf =3D READ_ONCE(cpudata->perf); =20 - policy->cpuinfo.min_freq =3D policy->min =3D perf_to_freq(perf, - cpudata->nominal_freq, - perf.lowest_perf); - policy->cpuinfo.max_freq =3D policy->max =3D perf_to_freq(perf, - cpudata->nominal_freq, - perf.highest_perf); + policy->cpuinfo.min_freq =3D perf_to_freq(perf, + cpudata->nominal_freq, + perf.lowest_perf); + policy->cpuinfo.max_freq =3D perf_to_freq(perf, + cpudata->nominal_freq, + perf.highest_perf); policy->driver_data =3D cpudata; =20 ret =3D amd_pstate_cppc_enable(policy); diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nf= orce2.c index fbbbe501cf2dc..831102522ad64 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -355,8 +355,8 @@ static int nforce2_cpu_init(struct cpufreq_policy *poli= cy) min_fsb =3D NFORCE2_MIN_FSB; =20 /* cpuinfo and default policy values */ - policy->min =3D policy->cpuinfo.min_freq =3D min_fsb * fid * 100; - policy->max =3D policy->cpuinfo.max_freq =3D max_fsb * fid * 100; + policy->cpuinfo.min_freq =3D min_fsb * fid * 100; + policy->cpuinfo.max_freq =3D max_fsb * fid * 100; =20 return 0; } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 20266fb42d18d..a855a77a5fa22 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1452,6 +1452,18 @@ static int cpufreq_policy_online(struct cpufreq_poli= cy *policy, cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); =20 if (new_policy) { + unsigned int min, max; + + /* + * If the driver has set policy->min or max, + * use the value as a QoS request. + */ + min =3D max(FREQ_QOS_MIN_DEFAULT_VALUE, policy->min); + if (policy->max) + max =3D min(FREQ_QOS_MAX_DEFAULT_VALUE, policy->max); + else + max =3D FREQ_QOS_MAX_DEFAULT_VALUE; + 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)); @@ -1466,7 +1478,7 @@ static int cpufreq_policy_online(struct cpufreq_polic= y *policy, =20 ret =3D freq_qos_add_request(&policy->constraints, policy->min_freq_req, FREQ_QOS_MIN, - FREQ_QOS_MIN_DEFAULT_VALUE); + min); if (ret < 0) { /* * So we don't call freq_qos_remove_request() for an @@ -1486,7 +1498,7 @@ static int cpufreq_policy_online(struct cpufreq_polic= y *policy, =20 ret =3D freq_qos_add_request(&policy->constraints, policy->max_freq_req, FREQ_QOS_MAX, - FREQ_QOS_MAX_DEFAULT_VALUE); + max); if (ret < 0) { policy->max_freq_req =3D NULL; goto out_destroy_policy; diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 75b3ef7ec6796..57999b8d51fa2 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -397,7 +397,7 @@ static int cpufreq_gx_target(struct cpufreq_policy *pol= icy, =20 static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) { - unsigned int maxfreq; + unsigned int minfreq, maxfreq; =20 if (!policy || policy->cpu !=3D 0) return -ENODEV; @@ -418,11 +418,10 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy = *policy) policy->cpu =3D 0; =20 if (max_duration < POLICY_MIN_DIV) - policy->min =3D maxfreq / max_duration; + minfreq =3D maxfreq / max_duration; else - policy->min =3D maxfreq / POLICY_MIN_DIV; - policy->max =3D maxfreq; - policy->cpuinfo.min_freq =3D maxfreq / max_duration; + minfreq =3D maxfreq / POLICY_MIN_DIV; + policy->cpuinfo.min_freq =3D minfreq; policy->cpuinfo.max_freq =3D maxfreq; =20 return 0; diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index ec4abe3745736..bf2f7524d04a9 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -3047,9 +3047,6 @@ static int __intel_pstate_cpu_init(struct cpufreq_pol= icy *policy) policy->cpuinfo.max_freq =3D READ_ONCE(global.no_turbo) ? cpu->pstate.max_freq : cpu->pstate.turbo_freq; =20 - policy->min =3D policy->cpuinfo.min_freq; - policy->max =3D policy->cpuinfo.max_freq; - intel_pstate_init_acpi_perf_limits(policy); =20 policy->fast_switch_possible =3D true; diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index ac2e90a65f0c4..231edfe8cabaa 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -551,13 +551,13 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy= *policy) goto out; } =20 - policy->max =3D policy->cpuinfo.max_freq =3D + policy->cpuinfo.max_freq =3D ioread32(&pcch_hdr->nominal) * 1000; - policy->min =3D policy->cpuinfo.min_freq =3D + policy->cpuinfo.min_freq =3D ioread32(&pcch_hdr->minimum_frequency) * 1000; =20 - pr_debug("init: policy->max is %d, policy->min is %d\n", - policy->max, policy->min); + pr_debug("init: max_freq is %d, min_freq is %d\n", + policy->cpuinfo.max_freq, policy->cpuinfo.min_freq); out: return result; } diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpuf= req.c index 4afa48d172dbe..f53b9d7edc76a 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -185,8 +185,8 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *p= olicy) int ret =3D -EINVAL; =20 /* set default policy and cpuinfo */ - policy->min =3D policy->cpuinfo.min_freq =3D 104000; - policy->max =3D policy->cpuinfo.max_freq =3D + policy->cpuinfo.min_freq =3D 104000; + policy->cpuinfo.max_freq =3D (cpu_is_pxa320()) ? 806000 : 624000; policy->cpuinfo.transition_latency =3D 1000; /* FIXME: 1 ms, assumed */ =20 diff --git a/drivers/cpufreq/virtual-cpufreq.c b/drivers/cpufreq/virtual-cp= ufreq.c index 6ffa16d239b2b..60707bf6ce1e3 100644 --- a/drivers/cpufreq/virtual-cpufreq.c +++ b/drivers/cpufreq/virtual-cpufreq.c @@ -164,10 +164,7 @@ static int virt_cpufreq_get_freq_info(struct cpufreq_p= olicy *policy) policy->cpuinfo.min_freq =3D 1; policy->cpuinfo.max_freq =3D virt_cpufreq_get_perftbl_entry(policy->cpu,= 0); =20 - policy->min =3D policy->cpuinfo.min_freq; - policy->max =3D policy->cpuinfo.max_freq; - - policy->cur =3D policy->max; + policy->cur =3D policy->cpuinfo.max_freq; return 0; } =20 --=20 2.43.0 From nobody Thu Apr 16 22:34:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B2D7325711; Wed, 25 Feb 2026 08:50:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009417; cv=none; b=YSOlDuxpPvTVowMHArGMtv6LdZVIfXWqZOYEhtoRPblQPY3jlS2HNjE/f7RHmxhLXM2PjZV1pd+IgPAoZMcJNyj+K95VqCO/uM2Xy2cHXdPSjFI07xgE9E9WP3RSTEBRKKcbC11+4UAY3I7MvvoccOywAITfhNdzRe9FQEjEStI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772009417; c=relaxed/simple; bh=dsB++htWglnJo1qJa8OcgIx7Ri+H3o9ijvfmCEjgPvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p6dPRRyOvCGAVqdjVgSzGLmYAMduF+mUyAWh9zuYWTC/BwSon9RR0GDG7yE9KYjE2Aq00A331dvShfnhrSLlLHmPsQqZM4sBua3A2OavCgIAsiwDaivhmnFctcJXDAQIe5TbXplzMoFY71G72t8MekX/e4disGfTXNnRuBZMKJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2926A169E; Wed, 25 Feb 2026 00:50:09 -0800 (PST) Received: from e135073.nice.arm.com (e135073.arm.com [10.34.125.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E3EAC3F59E; Wed, 25 Feb 2026 00:50:11 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Jie Zhan , Lifeng Zheng , Ionela Voinescu , Sumit Gupta , Christian Loehle , Pierre Gondois , "Rafael J. Wysocki" , Viresh Kumar , Huang Rui , "Gautham R. Shenoy" , Mario Limonciello , Perry Yuan , Srinivas Pandruvada , Len Brown , Saravana Kannan , linux-pm@vger.kernel.org Subject: [RFC PATCH v5 6/6] cpufreq/freq_table: Allow decreasing cpuinfo.max_freq Date: Wed, 25 Feb 2026 09:49:23 +0100 Message-ID: <20260225084930.1692228-7-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260225084930.1692228-1-pierre.gondois@arm.com> References: <20260225084930.1692228-1-pierre.gondois@arm.com> 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" Drivers not using freq. tables update cpuinfo.max_freq in their .set_boost() callback. E.g. amd-pstate, cppc_cpufreq. Drivers relying on freq. tables and supporting boost frequencies rely on cpufreq_frequency_table_cpuinfo(). cpuinfo.max_freq is only updated if the new maximal value is higher than the previous one. Using the scmi-cpufreq driver which relies on freq. tables, enabling boost will permanently increases the cpuinfo.max_freq value. This patch allows to lower cpuinfo.max_freq. Note: commit 538b0188da46 ("cpufreq: ACPI: Set cpuinfo.max_freq directly if max boost is known") favored having cpuinfo.max_freq reporting the maximal boosted frequency of a CPU instead of the maximal reachable frequency due to regressions in the frequency reported by cpuinfo.max and scaling_cur_freq. As stated above, this is not what most of the other cpufreq driver do. I assume that the following patch: commit 3c55e94c0ade ("cpufreq: ACPI: Extend frequency tables to cover boost frequencies") was correct, but might not have tagged the boosted frequency with the CPUFREQ_BOOST_FREQ flag in the freq. table. Signed-off-by: Pierre Gondois --- drivers/cpufreq/freq_table.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 9b37f37c36389..bd08cbe9e9ba3 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -50,12 +50,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_polic= y *policy) } policy->cpuinfo.min_freq =3D min_freq; - /* - * If the driver has set its own cpuinfo.max_freq above max_freq, leave - * it as is. - */ - if (policy->cpuinfo.max_freq < max_freq) - policy->cpuinfo.max_freq =3D max_freq; + policy->cpuinfo.max_freq =3D max_freq; if (min_freq =3D=3D ~0) return -EINVAL; -- 2.43.0