diff options
author | Jack Steiner <steiner@sgi.com> | 2011-11-15 18:33:56 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-12-05 11:12:43 -0500 |
commit | b565201cf75210614903ef2ae5917b4379681647 (patch) | |
tree | 6d28d33cf25a4fa47700b12d8e291886e1af195f /init/calibrate.c | |
parent | 1ea7c6737c8f68453f55c894b3d07d7f48fcbef8 (diff) |
x86: Reduce clock calibration time during slave cpu startup
Reduce the startup time for slave cpus.
Adds hooks for an arch-specific function for clock calibration.
These hooks are used on x86. If a newly started cpu has the
same phys_proc_id as a core already active, uses the TSC for the
delay loop and has a CONSTANT_TSC, use the already-calculated
value of loops_per_jiffy.
This patch reduces the time required to start slave cpus on a
4096 cpu system from: 465 sec OLD 62 sec NEW
This reduces boot time on a 4096p system by almost 7 minutes.
Nice...
Signed-off-by: Jack Steiner <steiner@sgi.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: John Stultz <john.stultz@linaro.org>
[fix CONFIG_SMP=n build]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'init/calibrate.c')
-rw-r--r-- | init/calibrate.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/init/calibrate.c b/init/calibrate.c index 24df7976816c..5f117ca9e069 100644 --- a/init/calibrate.c +++ b/init/calibrate.c | |||
@@ -246,6 +246,19 @@ recalibrate: | |||
246 | 246 | ||
247 | static DEFINE_PER_CPU(unsigned long, cpu_loops_per_jiffy) = { 0 }; | 247 | static DEFINE_PER_CPU(unsigned long, cpu_loops_per_jiffy) = { 0 }; |
248 | 248 | ||
249 | /* | ||
250 | * Check if cpu calibration delay is already known. For example, | ||
251 | * some processors with multi-core sockets may have all cores | ||
252 | * with the same calibration delay. | ||
253 | * | ||
254 | * Architectures should override this function if a faster calibration | ||
255 | * method is available. | ||
256 | */ | ||
257 | unsigned long __attribute__((weak)) __cpuinit calibrate_delay_is_known(void) | ||
258 | { | ||
259 | return 0; | ||
260 | } | ||
261 | |||
249 | void __cpuinit calibrate_delay(void) | 262 | void __cpuinit calibrate_delay(void) |
250 | { | 263 | { |
251 | unsigned long lpj; | 264 | unsigned long lpj; |
@@ -265,6 +278,8 @@ void __cpuinit calibrate_delay(void) | |||
265 | lpj = lpj_fine; | 278 | lpj = lpj_fine; |
266 | pr_info("Calibrating delay loop (skipped), " | 279 | pr_info("Calibrating delay loop (skipped), " |
267 | "value calculated using timer frequency.. "); | 280 | "value calculated using timer frequency.. "); |
281 | } else if ((lpj = calibrate_delay_is_known())) { | ||
282 | ; | ||
268 | } else if ((lpj = calibrate_delay_direct()) != 0) { | 283 | } else if ((lpj = calibrate_delay_direct()) != 0) { |
269 | if (!printed) | 284 | if (!printed) |
270 | pr_info("Calibrating delay using timer " | 285 | pr_info("Calibrating delay using timer " |