x86/idle: Select idle routine only once
authorThomas Gleixner <tglx@linutronix.de>
Wed, 28 Feb 2024 22:20:32 +0000 (23:20 +0100)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 4 Mar 2024 16:39:24 +0000 (17:39 +0100)
The idle routine selection is done on every CPU bringup operation and
has a guard in place which is effective after the first invocation,
which is a pointless exercise.

Invoke it once on the boot CPU and mark the related functions __init.
The guard check has to stay as xen_set_default_idle() runs early.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/87edcu6vaq.ffs@tglx
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/process.c

index 1188e8bf76a2998d9d8cb50d0da0ae9a9d28351e..523c466c2fc96941f3e0d09d40ed47f9273ee47a 100644 (file)
@@ -558,7 +558,7 @@ static inline void load_sp0(unsigned long sp0)
 
 unsigned long __get_wchan(struct task_struct *p);
 
-extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void select_idle_routine(void);
 extern void amd_e400_c1e_apic_setup(void);
 
 extern unsigned long           boot_option_idle_override;
index 8f367d3765208c215c3ad1f560ad5121295cf1e7..5c72af16dd06df92eefb3f8c0f26bdb828453892 100644 (file)
@@ -1938,8 +1938,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
        /* Init Machine Check Exception if available. */
        mcheck_cpu_init(c);
 
-       select_idle_routine(c);
-
 #ifdef CONFIG_NUMA
        numa_add_cpu(smp_processor_id());
 #endif
@@ -2344,6 +2342,8 @@ void __init arch_cpu_finalize_init(void)
 {
        identify_boot_cpu();
 
+       select_idle_routine();
+
        /*
         * identify_boot_cpu() initialized SMT support information, let the
         * core code know.
index ccaacc7f9681f7f00d5b8060f53fd7808947100a..f0166b31a803856e0b9e4f501d71bfdfee997662 100644 (file)
@@ -853,8 +853,9 @@ void __noreturn stop_this_cpu(void *dummy)
  * Do not prefer MWAIT if MONITOR instruction has a bug or idle=nomwait
  * is passed to kernel commandline parameter.
  */
-static bool prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
+static __init bool prefer_mwait_c1_over_halt(void)
 {
+       const struct cpuinfo_x86 *c = &boot_cpu_data;
        u32 eax, ebx, ecx, edx;
 
        /* If override is enforced on the command line, fall back to HALT. */
@@ -908,7 +909,7 @@ static __cpuidle void mwait_idle(void)
        __current_clr_polling();
 }
 
-void select_idle_routine(const struct cpuinfo_x86 *c)
+void __init select_idle_routine(void)
 {
        if (boot_option_idle_override == IDLE_POLL) {
                if (IS_ENABLED(CONFIG_SMP) && smp_num_siblings > 1)
@@ -916,10 +917,11 @@ void select_idle_routine(const struct cpuinfo_x86 *c)
                return;
        }
 
+       /* Required to guard against xen_set_default_idle() */
        if (x86_idle_set())
                return;
 
-       if (prefer_mwait_c1_over_halt(c)) {
+       if (prefer_mwait_c1_over_halt()) {
                pr_info("using mwait in idle threads\n");
                static_call_update(x86_idle, mwait_idle);
        } else if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {