Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: processor: perflib: Fix initial _PPC limit application

If the BIOS sets a _PPC frequency limit upfront, it will fail to take
effect due to a call ordering issue. Namely, freq_qos_update_request()
is called before freq_qos_add_request() for the given request causing
the constraint update to be ignored. The call sequence in question is
as follows:

cpufreq_policy_online()
acpi_cpufreq_cpu_init()
acpi_processor_register_performance()
acpi_processor_get_performance_info()
acpi_processor_get_platform_limit()
freq_qos_update_request(&perflib_req) <- inactive QoS request
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_CREATE_POLICY)
acpi_processor_notifier()
acpi_processor_ppc_init()
freq_qos_add_request(&perflib_req) <- QoS request activation

Address this by adding an acpi_processor_get_platform_limit() call
to acpi_processor_ppc_init(), after the perflib_req activation via
freq_qos_add_request(), which causes the initial _PPC limit to be
picked up as appropriate. However, also ensure that the _PPC limit
will not be picked up in the cases when the cpufreq driver does not
call acpi_processor_register_performance() by adding a pr->performance
check to the related_cpus loop in acpi_processor_ppc_init().

Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier")
Signed-off-by: Jiayi Li <lijiayi@kylinos.cn>
Link: https://patch.msgid.link/20250721032606.3459369-1-lijiayi@kylinos.cn
[ rjw: Consolidate pr-related checks in acpi_processor_ppc_init() ]
[ rjw: Subject and changelog adjustments ]
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+: 2d8b39a62a5d ACPI: processor: Avoid NULL pointer dereferences at init time
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+: 3000ce3c52f8 cpufreq: Use per-policy frequency QoS
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+: a1bb46c36ce3 ACPI: processor: Add QoS requests for all CPUs
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Jiayi Li and committed by
Rafael J. Wysocki
d33bd88a 13edf753

+9 -1
+9 -1
drivers/acpi/processor_perflib.c
··· 173 173 { 174 174 unsigned int cpu; 175 175 176 + if (ignore_ppc == 1) 177 + return; 178 + 176 179 for_each_cpu(cpu, policy->related_cpus) { 177 180 struct acpi_processor *pr = per_cpu(processors, cpu); 178 181 int ret; 179 182 180 - if (!pr) 183 + if (!pr || !pr->performance) 181 184 continue; 182 185 183 186 /* ··· 195 192 FREQ_QOS_MAX_DEFAULT_VALUE); 196 193 if (ret < 0) 197 194 pr_err("Failed to add freq constraint for CPU%d (%d)\n", 195 + cpu, ret); 196 + 197 + ret = acpi_processor_get_platform_limit(pr); 198 + if (ret) 199 + pr_err("Failed to update freq constraint for CPU%d (%d)\n", 198 200 cpu, ret); 199 201 } 200 202 }