Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/aperfmperf: Separate AP/BP frequency invariance init

This code is convoluted and because it can be invoked post init via the
ACPI/CPPC code, all of the initialization functionality is built in instead
of being part of init text and init data.

As a first step create separate calls for the boot and the application
processors.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://lore.kernel.org/r/20220415161206.536733494@linutronix.de

+20 -22
+5 -7
arch/x86/include/asm/topology.h
··· 216 216 #define arch_scale_freq_tick arch_scale_freq_tick 217 217 218 218 extern void arch_set_max_freq_ratio(bool turbo_disabled); 219 - void init_freq_invariance(bool secondary, bool cppc_ready); 219 + extern void bp_init_freq_invariance(bool cppc_ready); 220 + extern void ap_init_freq_invariance(void); 220 221 #else 221 - static inline void arch_set_max_freq_ratio(bool turbo_disabled) 222 - { 223 - } 224 - static inline void init_freq_invariance(bool secondary, bool cppc_ready) 225 - { 226 - } 222 + static inline void arch_set_max_freq_ratio(bool turbo_disabled) { } 223 + static inline void bp_init_freq_invariance(bool cppc_ready) { } 224 + static inline void ap_init_freq_invariance(void) { } 227 225 #endif 228 226 229 227 #ifdef CONFIG_ACPI_CPPC_LIB
+2 -1
arch/x86/kernel/acpi/cppc.c
··· 96 96 97 97 mutex_lock(&freq_invariance_lock); 98 98 99 - init_freq_invariance(secondary, true); 99 + if (!secondary) 100 + bp_init_freq_invariance(true); 100 101 secondary = true; 101 102 102 103 mutex_unlock(&freq_invariance_lock);
+11 -12
arch/x86/kernel/cpu/aperfmperf.c
··· 428 428 static inline void register_freq_invariance_syscore_ops(void) {} 429 429 #endif 430 430 431 - void init_freq_invariance(bool secondary, bool cppc_ready) 431 + void bp_init_freq_invariance(bool cppc_ready) 432 432 { 433 - bool ret = false; 433 + bool ret; 434 434 435 - if (!boot_cpu_has(X86_FEATURE_APERFMPERF)) 435 + if (!cpu_feature_enabled(X86_FEATURE_APERFMPERF)) 436 436 return; 437 437 438 - if (secondary) { 439 - if (static_branch_likely(&arch_scale_freq_key)) { 440 - init_counter_refs(); 441 - } 442 - return; 443 - } 438 + init_counter_refs(); 444 439 445 440 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) 446 441 ret = intel_set_max_freq_ratio(); 447 442 else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { 448 - if (!cppc_ready) { 443 + if (!cppc_ready) 449 444 return; 450 - } 451 445 ret = amd_set_max_freq_ratio(&arch_turbo_freq_ratio); 452 446 } 453 447 454 448 if (ret) { 455 - init_counter_refs(); 456 449 static_branch_enable(&arch_scale_freq_key); 457 450 register_freq_invariance_syscore_ops(); 458 451 pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); 459 452 } else { 460 453 pr_debug("Couldn't determine max cpu frequency, necessary for scale-invariant accounting.\n"); 461 454 } 455 + } 456 + 457 + void ap_init_freq_invariance(void) 458 + { 459 + if (cpu_feature_enabled(X86_FEATURE_APERFMPERF)) 460 + init_counter_refs(); 462 461 } 463 462 464 463 static void disable_freq_invariance_workfn(struct work_struct *work)
+2 -2
arch/x86/kernel/smpboot.c
··· 186 186 */ 187 187 set_cpu_sibling_map(raw_smp_processor_id()); 188 188 189 - init_freq_invariance(true, false); 189 + ap_init_freq_invariance(); 190 190 191 191 /* 192 192 * Get our bogomips. ··· 1396 1396 { 1397 1397 smp_prepare_cpus_common(); 1398 1398 1399 - init_freq_invariance(false, false); 1399 + bp_init_freq_invariance(false); 1400 1400 smp_sanity_check(); 1401 1401 1402 1402 switch (apic_intr_mode) {