| From stable+bounces-187850-greg=kroah.com@vger.kernel.org Sat Oct 18 18:13:48 2025 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 18 Oct 2025 12:13:41 -0400 |
| Subject: cpufreq: CPPC: Avoid using CPUFREQ_ETERNAL as transition delay |
| To: stable@vger.kernel.org |
| Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>, "Mario Limonciello (AMD)" <superm1@kernel.org>, Jie Zhan <zhanjie9@hisilicon.com>, Viresh Kumar <viresh.kumar@linaro.org>, Qais Yousef <qyousef@layalina.io>, Sasha Levin <sashal@kernel.org> |
| Message-ID: <20251018161341.836384-1-sashal@kernel.org> |
| |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| |
| [ Upstream commit f965d111e68f4a993cc44d487d416e3d954eea11 ] |
| |
| If cppc_get_transition_latency() returns CPUFREQ_ETERNAL to indicate a |
| failure to retrieve the transition latency value from the platform |
| firmware, the CPPC cpufreq driver will use that value (converted to |
| microseconds) as the policy transition delay, but it is way too large |
| for any practical use. |
| |
| Address this by making the driver use the cpufreq's default |
| transition latency value (in microseconds) as the transition delay |
| if CPUFREQ_ETERNAL is returned by cppc_get_transition_latency(). |
| |
| Fixes: d4f3388afd48 ("cpufreq / CPPC: Set platform specific transition_delay_us") |
| Cc: 5.19+ <stable@vger.kernel.org> # 5.19 |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> |
| Reviewed-by: Jie Zhan <zhanjie9@hisilicon.com> |
| Acked-by: Viresh Kumar <viresh.kumar@linaro.org> |
| Reviewed-by: Qais Yousef <qyousef@layalina.io> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/cpufreq/cppc_cpufreq.c | 14 ++++++++++++-- |
| 1 file changed, 12 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/cpufreq/cppc_cpufreq.c |
| +++ b/drivers/cpufreq/cppc_cpufreq.c |
| @@ -339,6 +339,16 @@ static int cppc_verify_policy(struct cpu |
| return 0; |
| } |
| |
| +static unsigned int __cppc_cpufreq_get_transition_delay_us(unsigned int cpu) |
| +{ |
| + unsigned int transition_latency_ns = cppc_get_transition_latency(cpu); |
| + |
| + if (transition_latency_ns == CPUFREQ_ETERNAL) |
| + return CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS / NSEC_PER_USEC; |
| + |
| + return transition_latency_ns / NSEC_PER_USEC; |
| +} |
| + |
| /* |
| * The PCC subspace describes the rate at which platform can accept commands |
| * on the shared PCC channel (including READs which do not count towards freq |
| @@ -361,12 +371,12 @@ static unsigned int cppc_cpufreq_get_tra |
| return 10000; |
| } |
| } |
| - return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; |
| + return __cppc_cpufreq_get_transition_delay_us(cpu); |
| } |
| #else |
| static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) |
| { |
| - return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; |
| + return __cppc_cpufreq_get_transition_delay_us(cpu); |
| } |
| #endif |
| |