Commit f97aef09 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

cpufreq: Make drivers using CPUFREQ_ETERNAL specify transition latency

Commit a755d0e2 ("cpufreq: Honour transition_latency over
transition_delay_us") caused platforms where cpuinfo.transition_latency
is CPUFREQ_ETERNAL to get a very large transition latency whereas
previously it had been capped at 10 ms (and later at 2 ms).

This led to a user-observable regression between 6.6 and 6.12 as
described by Shawn:

"The dbs sampling_rate was 10000 us on 6.6 and suddently becomes
 6442450 us (4294967295 / 1000 * 1.5) on 6.12 for these platforms
 because the default transition delay was dropped [...].

 It slows down dbs governor's reacting to CPU loading change
 dramatically.  Also, as transition_delay_us is used by schedutil
 governor as rate_limit_us, it shows a negative impact on device
 idle power consumption, because the device gets slightly less time
 in the lowest OPP."

Evidently, the expectation of the drivers using CPUFREQ_ETERNAL as
cpuinfo.transition_latency was that it would be capped by the core,
but they may as well return a default transition latency value instead
of CPUFREQ_ETERNAL and the core need not do anything with it.

Accordingly, introduce CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS and make
all of the drivers in question use it instead of CPUFREQ_ETERNAL.  Also
update the related Rust binding.

Fixes: a755d0e2 ("cpufreq: Honour transition_latency over transition_delay_us")
Closes: https://lore.kernel.org/linux-pm/20250922125929.453444-1-shawnguo2@yeah.net/


Reported-by: default avatarShawn Guo <shawnguo@kernel.org>
Reviewed-by: default avatarMario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: default avatarJie Zhan <zhanjie9@hisilicon.com>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Cc: 6.6+ <stable@vger.kernel.org> # 6.6+
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/2264949.irdbgypaU6@rafael.j.wysocki


[ rjw: Fix typo in new symbol name, drop redundant type cast from Rust binding ]
Tested-by: Shawn Guo <shawnguo@kernel.org> # with cpufreq-dt driver
Reviewed-by: default avatarQais Yousef <qyousef@layalina.io>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d3f8f8d0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)

	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
	if (!transition_latency)
		transition_latency = CPUFREQ_ETERNAL;
		transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;

	cpumask_copy(policy->cpus, priv->cpus);
	policy->driver_data = priv;
+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
	}

	if (of_property_read_u32(np, "clock-latency", &transition_latency))
		transition_latency = CPUFREQ_ETERNAL;
		transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;

	/*
	 * Calculate the ramp time for max voltage change in the
+1 −1
Original line number Diff line number Diff line
@@ -309,7 +309,7 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)

	latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000;
	if (!latency)
		latency = CPUFREQ_ETERNAL;
		latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;

	policy->cpuinfo.transition_latency = latency;
	policy->fast_switch_possible = true;
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {

        let mut transition_latency = opp_table.max_transition_latency_ns() as u32;
        if transition_latency == 0 {
            transition_latency = cpufreq::ETERNAL_LATENCY_NS;
            transition_latency = cpufreq::DEFAULT_TRANSITION_LATENCY_NS;
        }

        policy
+1 −1
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)

	latency = perf_ops->transition_latency_get(ph, domain);
	if (!latency)
		latency = CPUFREQ_ETERNAL;
		latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;

	policy->cpuinfo.transition_latency = latency;

Loading