When a power notification event occurs, existing ACPI idle states may
become obsolete. The current implementation only performs a partial
update, leaving critical cpuidle parameters, like target_residency_ns
and exit_latency_ns, stale. Furthermore, per-CPU cpuidle_device data,
including last_residency_ns, states_usage, and the disable flag, are not
properly synchronized. Using these stale values leads to incorrect power
management decisions.
To ensure all parameters are correctly synchronized, modify the
notification handling logic:
1. Unregister all cpuidle_device instances to ensure a clean slate.
2. Unregister and re-register the ACPI idle driver. This forces the
framework to re-evaluate global state parameters and ensures the
driver state matches the new hardware power profile.
3. Re-initialize power information and re-register cpuidle_device for
all possible CPUs to restore functional idle management.
This complete reset ensures that the cpuidle framework and the underlying
ACPI states are perfectly synchronized after a power state change.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Subject rewrite ]
Link: https://patch.msgid.link/20260407081141.2493581-3-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
A cpuidle_device might fail to register during boot, but the system can
continue to run. In such cases, acpi_processor_hotplug() can trigger
a NULL pointer dereference when accessing the per-cpu acpi_cpuidle_device.
So add NULL pointer check for the per-cpu acpi_cpuidle_device in
acpi_processor_hotplug.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Link: https://patch.msgid.link/20260403090253.998322-1-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The 'power_setup_done' flag is a key indicator used across the ACPI
processor driver to determine if cpuidle are properly configured and
available for a given CPU.
Currently, this flag is set during the early stages of initialization.
However, if the subsequent registration of the cpuidle driver in
acpi_processor_register_idle_driver() or the per-CPU device registration
in acpi_processor_power_init() fails, this flag remains set. This may
lead to some issues where other functions in ACPI idle driver use these
flags.
Fix this by explicitly resetting this flag to 0 in these error paths.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Link: https://patch.msgid.link/20260403085343.866440-1-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The function acpi_processor_cstate_first_run_checks() is currently called
only once during initialization in acpi_processor_register_idle_driver().
Since its execution is already limited by the caller's lifecycle, the
internal static 'first_run' variable is redundant and can be safely
removed.
Additionally, the current function name is no longer descriptive of its
behavior, so rename the function to acpi_processor_update_max_cstate()
to better reflect its actual purpose.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Link: https://patch.msgid.link/20260311065038.4151558-4-lihuisong@huawei.com
[ rjw: Changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The function acpi_processor_cstate_first_run_checks() is responsible
for updating max_cstate and performing initial hardware validation.
Currently, this function is invoked within acpi_processor_power_init().
However, the initialization flow already ensures this is called during
acpi_processor_register_idle_driver(). Therefore, the call in
acpi_processor_power_init() is redundant and effectively performs no work,
so remove it.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Link: https://patch.msgid.link/20260311065038.4151558-2-lihuisong@huawei.com
[ rjw: Changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The inner loop in flatten_lpi_states() that combines composite LPI
states can increment flat_state_cnt multiple times within the loop.
The condition that guards this (checks bounds against ACPI_PROCESSOR
_MAX_POWER) occurs at the top of the outer loop. flat_state_cnt might
exceed ACPI_PROCESSOR_MAX_POWER if it is incremented multiple times
within the inner loop between outer loop iterations.
Add a bounds check after the increment inside the inner loop so that
it breaks out when flat_state_cnt reaches ACPI_PROCESSOR_MAX_POWER.
The existing check in the outer loop will then handle the warning.
Signed-off-by: Jingkai Tan <contact@jingk.ai>
Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
Link: https://patch.msgid.link/20260305213831.53985-1-contact@jingk.ai
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:
Single allocations: kmalloc(sizeof(TYPE), ...)
are replaced with: kmalloc_obj(TYPE, ...)
Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with: kmalloc_objs(TYPE, COUNT, ...)
Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...)
(where TYPE may also be *VAR)
The resulting allocations no longer return "void *", instead returning
"TYPE *".
Signed-off-by: Kees Cook <kees@kernel.org>
Move the acpi_processor_ffh_lpi_probe() call from
acpi_processor_setup_cpuidle_dev(), where its return value is
ignored, to acpi_processor_get_power_info(), which can take the
return value of that function into account in a meaningful way
and generally is a more suitable place for calling it.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Message adjustment, subject and changelog edits ]
Link: https://patch.msgid.link/20260120112258.1595164-4-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Since all callers of acpi_processor_setup_cpuidle_states() ignore its
return value and it simply passes the acpi_processor_setup_lpi_states()
return value to its callers, convert both of these functions to void.
No intentional functional impact.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Subject and changelog edits ]
Link: https://patch.msgid.link/20260120112258.1595164-2-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
According to ACPI spec, entry method in LPI sub-package must be a
buffer or an integer.
The driver will disable the state whose the entry method is invalid
by zeroing flags in struct acpi_lpi_state.
The entry method is very key in cpuidle. A debug log is very useful
for developers.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
[ rjw: Subject and changelog edits, changed "illegal" to "invalid" ]
Link: https://patch.msgid.link/20251125064702.3666149-1-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Notice that acpi_processor_power_init() and acpi_processor_power_exit()
don't need to return any values because their callers don't check them
anyway, so redefine those functions as void.
While at it, rearrange the code in acpi_processor_power_init() to
reduce the indentation level, get rid of a redundant local variable
in that function, and rephrase a code comment in it.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Tested-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://patch.msgid.link/20251223100914.2407069-5-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Currently, the ACPI idle driver is registered from within a CPU
hotplug callback. Although this didn't cause any functional issues,
this is questionable and confusing. And it is better to register
the cpuidle driver when all of the CPUs have been brought up.
So add a new function to initialize acpi_idle_driver based on the
power management information of an available CPU and register cpuidle
driver in acpi_processor_driver_init().
This commit has four changes under the commit 7a8c994cbb (ACPI:
processor: idle: Optimize ACPI idle driver registration):
1) move acpi_processor_register_idle_driver() ahead of the
driver_register().
2) add acpi_processor_cstate_first_run_checks() before calling
acpi_processor_get_power_info().
3) squash the commit 9d68320b2b (ACPI: processor: idle: Fix
function defined but not used warning) into this change.
4) use for_each_possible_cpu(cpu) to scan all possible cpus.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Tested-by: Borislav Petkov (AMD) <bp@alien8.de>
[ rjw: New comment edits, changelog tweak ]
Link: https://patch.msgid.link/20251223100914.2407069-2-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Revert commit fbd401e95e ("ACPI: processor: idle: Redefine two
functions as void") because it depends on a problematic one.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Revert commit 559f2eacc8 ACPI: processor: Do not expose global variable
acpi_idle_driver" because it depends on a problematic one.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
acpi_processor_setup_cstates() and acpi_processor_setup_cpuidle_cx()
are called after successfully obtaining power information. Among other
things, these setup functions check the C-state count against zero.
However, that check is done by acpi_processor_get_power_info_cst()
which will cause acpi_processor_get_power_info() to fail if it does
no pass, so the checks in the two functions mentioned above are
redundant.
Drop those redundant checks.
No intentional functional impact.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Subject and changelog rewrite ]
Link: https://patch.msgid.link/20251105093647.3557248-1-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Since acpi_processor_setup_cstates() is a more logical place for setting
idle state flags than acpi_processor_setup_cpuidle_cx(), move that code
from the latter to the former.
It also allows direct references to acpi_idle_driver in
acpi_processor_setup_cpuidle_cx() to be avoided.
No intentional functional impact.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Subject and changelog rewrite ]
Link: https://patch.msgid.link/20250929093754.3998136-5-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Notice that acpi_processor_power_init() and acpi_processor_power_exit()
don't need to return any values because their callers don't check them
anyway, so redefine those functions as void.
While at it, rearrange the code in acpi_processor_power_init() to
reduce the indentation level, get rid of a redundant local variable
in that function, and rephrase a code comment in it.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>