ACPI: processor: Rescan "dead" SMT siblings during initialization

JIRA: https://issues.redhat.com/browse/RHEL-113139

commit f694481b1d3177144fcac4242eb750cfcb9f7bd5
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Date:   Thu Jun 5 17:07:31 2025 +0200

    ACPI: processor: Rescan "dead" SMT siblings during initialization

    Make acpi_processor_driver_init() call arch_cpu_rescan_dead_smt_siblings(),
    via a new wrapper function called acpi_idle_rescan_dead_smt_siblings(),
    after successfully initializing the driver, to allow the "dead" SMT
    siblings to go into deep idle states, which is necessary for the
    processor to be able to reach deep package C-states (like PC10) going
    forward, so that power can be reduced sufficiently in suspend-to-idle,
    among other things.

    However, do it only if the ACPI idle driver is the current cpuidle
    driver (otherwise it is assumed that another cpuidle driver will take
    care of this) and avoid doing it on architectures other than x86.

    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
    Link: https://patch.msgid.link/2005721.PYKUYFuaPT@rjwysocki.net

Signed-off-by: David Arcari <darcari@redhat.com>
This commit is contained in:
David Arcari 2025-09-05 07:58:02 -04:00
parent 235c38cd09
commit a5038b59ef
3 changed files with 17 additions and 0 deletions

View File

@ -174,6 +174,12 @@ bool processor_physically_present(acpi_handle handle);
static inline void acpi_early_processor_control_setup(void) {} static inline void acpi_early_processor_control_setup(void) {}
#endif #endif
#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
void acpi_idle_rescan_dead_smt_siblings(void);
#else
static inline void acpi_idle_rescan_dead_smt_siblings(void) {}
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Embedded Controller Embedded Controller
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */

View File

@ -298,6 +298,9 @@ static int __init acpi_processor_driver_init(void)
* after acpi_cppc_processor_probe() has been called for all online CPUs * after acpi_cppc_processor_probe() has been called for all online CPUs
*/ */
acpi_processor_init_invariance_cppc(); acpi_processor_init_invariance_cppc();
acpi_idle_rescan_dead_smt_siblings();
return 0; return 0;
err: err:
driver_unregister(&acpi_processor_driver); driver_unregister(&acpi_processor_driver);

View File

@ -24,6 +24,8 @@
#include <acpi/processor.h> #include <acpi/processor.h>
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include "internal.h"
/* /*
* Include the apic definitions for x86 to have the APIC timer related defines * Include the apic definitions for x86 to have the APIC timer related defines
* available also for UP (on SMP it gets magically included via linux/smp.h). * available also for UP (on SMP it gets magically included via linux/smp.h).
@ -55,6 +57,12 @@ struct cpuidle_driver acpi_idle_driver = {
}; };
#ifdef CONFIG_ACPI_PROCESSOR_CSTATE #ifdef CONFIG_ACPI_PROCESSOR_CSTATE
void acpi_idle_rescan_dead_smt_siblings(void)
{
if (cpuidle_get_driver() == &acpi_idle_driver)
arch_cpu_rescan_dead_smt_siblings();
}
static static
DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate); DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate);