x86/smp: PM/hibernate: Split arch_resume_nosmt()
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 7 Jun 2025 12:22:56 +0000 (14:22 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 7 Jun 2025 12:22:56 +0000 (14:22 +0200)
Move the inner part of the arch_resume_nosmt() code into a separate
function called arch_cpu_rescan_dead_smt_siblings(), so it can be
used in other places where "dead" SMT siblings may need to be taken
online and offline again in order to get into deep idle states.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Link: https://patch.msgid.link/3361688.44csPzL39Z@rjwysocki.net
[ rjw: Prevent build issues with CONFIG_SMP unset ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
arch/x86/kernel/smp.c
arch/x86/power/hibernate.c
include/linux/cpu.h

index 18266cc3d98c182a3822ebf6c025924442994edb..b014e6d229f9519add6f3fb315f1a2f375675a50 100644 (file)
@@ -299,3 +299,27 @@ struct smp_ops smp_ops = {
        .send_call_func_single_ipi = native_send_call_func_single_ipi,
 };
 EXPORT_SYMBOL_GPL(smp_ops);
+
+int arch_cpu_rescan_dead_smt_siblings(void)
+{
+       enum cpuhp_smt_control old = cpu_smt_control;
+       int ret;
+
+       /*
+        * If SMT has been disabled and SMT siblings are in HLT, bring them back
+        * online and offline them again so that they end up in MWAIT proper.
+        *
+        * Called with hotplug enabled.
+        */
+       if (old != CPU_SMT_DISABLED && old != CPU_SMT_FORCE_DISABLED)
+               return 0;
+
+       ret = cpuhp_smt_enable();
+       if (ret)
+               return ret;
+
+       ret = cpuhp_smt_disable(old);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(arch_cpu_rescan_dead_smt_siblings);
index a7c23f2a58c994c0d3de553fa6fe944660995d28..a2294c1649f65e43cdac025a5a315fe6222754fd 100644 (file)
@@ -192,7 +192,8 @@ out:
 
 int arch_resume_nosmt(void)
 {
-       int ret = 0;
+       int ret;
+
        /*
         * We reached this while coming out of hibernation. This means
         * that SMT siblings are sleeping in hlt, as mwait is not safe
@@ -206,18 +207,10 @@ int arch_resume_nosmt(void)
         * Called with hotplug disabled.
         */
        cpu_hotplug_enable();
-       if (cpu_smt_control == CPU_SMT_DISABLED ||
-                       cpu_smt_control == CPU_SMT_FORCE_DISABLED) {
-               enum cpuhp_smt_control old = cpu_smt_control;
-
-               ret = cpuhp_smt_enable();
-               if (ret)
-                       goto out;
-               ret = cpuhp_smt_disable(old);
-               if (ret)
-                       goto out;
-       }
-out:
+
+       ret = arch_cpu_rescan_dead_smt_siblings();
+
        cpu_hotplug_disable();
+
        return ret;
 }
index e6089abc28e2c825e48984a15bd748b477670760..96a3a0d6a60edc27db4c2b83448002782ca74c5f 100644 (file)
@@ -120,6 +120,7 @@ extern void cpu_maps_update_begin(void);
 extern void cpu_maps_update_done(void);
 int bringup_hibernate_cpu(unsigned int sleep_cpu);
 void bringup_nonboot_cpus(unsigned int max_cpus);
+int arch_cpu_rescan_dead_smt_siblings(void);
 
 #else  /* CONFIG_SMP */
 #define cpuhp_tasks_frozen     0
@@ -134,6 +135,8 @@ static inline void cpu_maps_update_done(void)
 
 static inline int add_cpu(unsigned int cpu) { return 0;}
 
+static inline int arch_cpu_rescan_dead_smt_siblings(void) { return 0; }
+
 #endif /* CONFIG_SMP */
 extern const struct bus_type cpu_subsys;