Commit 134a1282 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Peter Zijlstra

x86/smpboot: Avoid pointless delay calibration if TSC is synchronized

When TSC is synchronized across sockets then there is no reason to
calibrate the delay for the first CPU which comes up on a socket.

Just reuse the existing calibration value.

This removes 100ms pointlessly wasted time from CPU hotplug per socket.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarMichael Kelley <mikelley@microsoft.com>
Tested-by: default avatarOleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Helge Deller <deller@gmx.de> # parisc
Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck
Link: https://lore.kernel.org/r/20230512205255.608773568@linutronix.de
parent ba831b7b
......@@ -178,28 +178,17 @@ static void smp_callin(void)
*/
apic_ap_setup();
/*
* Save our processor parameters. Note: this information
* is needed for clock calibration.
*/
/* Save our processor parameters. */
smp_store_cpu_info(cpuid);
/*
* The topology information must be up to date before
* calibrate_delay() and notify_cpu_starting().
* notify_cpu_starting().
*/
set_cpu_sibling_map(raw_smp_processor_id());
ap_init_aperfmperf();
/*
* Get our bogomips.
* Update loops_per_jiffy in cpu_data. Previous call to
* smp_store_cpu_info() stored a value that is close but not as
* accurate as the value just calculated.
*/
calibrate_delay();
cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy;
pr_debug("Stack at about %p\n", &cpuid);
wmb();
......@@ -212,8 +201,24 @@ static void smp_callin(void)
cpumask_set_cpu(cpuid, cpu_callin_mask);
}
static void ap_calibrate_delay(void)
{
/*
* Calibrate the delay loop and update loops_per_jiffy in cpu_data.
* smp_store_cpu_info() stored a value that is close but not as
* accurate as the value just calculated.
*
* As this is invoked after the TSC synchronization check,
* calibrate_delay_is_known() will skip the calibration routine
* when TSC is synchronized across sockets.
*/
calibrate_delay();
cpu_data(smp_processor_id()).loops_per_jiffy = loops_per_jiffy;
}
static int cpu0_logical_apicid;
static int enable_start_cpu0;
/*
* Activate a secondary processor.
*/
......@@ -240,10 +245,15 @@ static void notrace start_secondary(void *unused)
/* otherwise gcc will move up smp_processor_id before the cpu_init */
barrier();
/* Check TSC synchronization with the control CPU: */
check_tsc_sync_target();
/*
* Check TSC synchronization with the boot CPU:
* Calibrate the delay loop after the TSC synchronization check.
* This allows to skip the calibration when TSC is synchronized
* across sockets.
*/
check_tsc_sync_target();
ap_calibrate_delay();
speculative_store_bypass_ht_init();
......
......@@ -1598,10 +1598,7 @@ void __init tsc_init(void)
#ifdef CONFIG_SMP
/*
* If we have a constant TSC and are using the TSC for the delay loop,
* we can skip clock calibration if another cpu in the same socket has already
* been calibrated. This assumes that CONSTANT_TSC applies to all
* cpus in the socket - this should be a safe assumption.
* Check whether existing calibration data can be reused.
*/
unsigned long calibrate_delay_is_known(void)
{
......@@ -1609,6 +1606,21 @@ unsigned long calibrate_delay_is_known(void)
int constant_tsc = cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC);
const struct cpumask *mask = topology_core_cpumask(cpu);
/*
* If TSC has constant frequency and TSC is synchronized across
* sockets then reuse CPU0 calibration.
*/
if (constant_tsc && !tsc_unstable)
return cpu_data(0).loops_per_jiffy;
/*
* If TSC has constant frequency and TSC is not synchronized across
* sockets and this is not the first CPU in the socket, then reuse
* the calibration value of an already online CPU on that socket.
*
* This assumes that CONSTANT_TSC is consistent for all CPUs in a
* socket.
*/
if (!constant_tsc || !mask)
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment