]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ACPI: processor: Rescan "dead" SMT siblings during initialization
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 5 Jun 2025 15:07:31 +0000 (17:07 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 7 Jun 2025 12:23:22 +0000 (14:23 +0200)
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
drivers/acpi/internal.h
drivers/acpi/processor_driver.c
drivers/acpi/processor_idle.c

index 00910ccd7eda81de382d4a1c249bf43280e2a777..e2781864fdcebd54cc3a16ae33f3a7ec36fd5754 100644 (file)
@@ -175,6 +175,12 @@ bool processor_physically_present(acpi_handle handle);
 static inline void acpi_early_processor_control_setup(void) {}
 #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
    -------------------------------------------------------------------------- */
index 3b281bc1e73c3b35f76cbad1e3207e7907dc05c0..65e779be64ffcc6b728fc1b78df14435514c45db 100644 (file)
@@ -279,6 +279,9 @@ static int __init acpi_processor_driver_init(void)
         * after acpi_cppc_processor_probe() has been called for all online CPUs
         */
        acpi_processor_init_invariance_cppc();
+
+       acpi_idle_rescan_dead_smt_siblings();
+
        return 0;
 err:
        driver_unregister(&acpi_processor_driver);
index e2febca2ec13e0d88e879cfd2f63c4844b81eec5..2c2dc559e0f8def8469f3b94f2d7935f2cdb78a4 100644 (file)
@@ -24,6 +24,8 @@
 #include <acpi/processor.h>
 #include <linux/context_tracking.h>
 
+#include "internal.h"
+
 /*
  * 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).
@@ -55,6 +57,12 @@ struct cpuidle_driver acpi_idle_driver = {
 };
 
 #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
 DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate);