diff options
| author | Andi Kleen <ak@suse.de> | 2005-08-19 00:56:40 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-19 22:18:47 -0400 |
| commit | 1eecd73cce4e11ba9d67ad767f92069cfba7b589 (patch) | |
| tree | c72bdb38231e163df346ba118af821e4875c95bb /arch | |
| parent | 5e5ec10499a00bf4ce3440d5a9e1a5a176c5a640 (diff) | |
[PATCH] x86_64: Fix race in TSC synchronization
Plug a race in TSC synchronization
We need to do tsc_sync_wait() before the CPU is set online to prevent
multiple CPUs from doing it in parallel - which won't work because TSC
sync has global unprotected state.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/kernel/smpboot.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index b15761ff4101..fa25e39fe54d 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
| @@ -492,6 +492,14 @@ void __cpuinit start_secondary(void) | |||
| 492 | */ | 492 | */ |
| 493 | set_cpu_sibling_map(smp_processor_id()); | 493 | set_cpu_sibling_map(smp_processor_id()); |
| 494 | 494 | ||
| 495 | /* | ||
| 496 | * Wait for TSC sync to not schedule things before. | ||
| 497 | * We still process interrupts, which could see an inconsistent | ||
| 498 | * time in that window unfortunately. | ||
| 499 | * Do this here because TSC sync has global unprotected state. | ||
| 500 | */ | ||
| 501 | tsc_sync_wait(); | ||
| 502 | |||
| 495 | /* | 503 | /* |
| 496 | * We need to hold call_lock, so there is no inconsistency | 504 | * We need to hold call_lock, so there is no inconsistency |
| 497 | * between the time smp_call_function() determines number of | 505 | * between the time smp_call_function() determines number of |
| @@ -509,13 +517,6 @@ void __cpuinit start_secondary(void) | |||
| 509 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 517 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
| 510 | unlock_ipi_call_lock(); | 518 | unlock_ipi_call_lock(); |
| 511 | 519 | ||
| 512 | mb(); | ||
| 513 | |||
| 514 | /* Wait for TSC sync to not schedule things before. | ||
| 515 | We still process interrupts, which could see an inconsistent | ||
| 516 | time in that window unfortunately. */ | ||
| 517 | tsc_sync_wait(); | ||
| 518 | |||
| 519 | cpu_idle(); | 520 | cpu_idle(); |
| 520 | } | 521 | } |
| 521 | 522 | ||
