summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2005-07-29 14:03:29 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-29 15:01:13 -0700
commit3d483f47579461a4715db33c68ef8752e5a97a2d (patch)
tree6a4c9022074426d3551ff1b47c95f2bfe3f41828 /include
parent94d2ac66c12397e2ca7988dbf59f24a966d275cb (diff)
downloadlinux-3.10-3d483f47579461a4715db33c68ef8752e5a97a2d.tar.gz
linux-3.10-3d483f47579461a4715db33c68ef8752e5a97a2d.tar.bz2
linux-3.10-3d483f47579461a4715db33c68ef8752e5a97a2d.zip
[PATCH] Fix sync_tsc hang
sync_tsc was using smp_call_function to ask the boot processor to report it's tsc value. smp_call_function performs an IPI_send_allbutself which is a broadcast ipi. There is a window during processor startup during which the target cpu has started and before it has initialized it's interrupt vectors so it can properly process an interrupt. Receveing an interrupt during that window will triple fault the cpu and do other nasty things. Why cli does not protect us from that is beyond me. The simple fix is to match ia64 and provide a smp_call_function_single. Which avoids the broadcast and is more efficient. This certainly fixes the problem of getting stuck on boot which was very easy to trigger on my SMP Hyperthreaded Xeon, and I think it fixes it for the right reasons. Minor changes by AK Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-x86_64/smp.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index 18ac762e1ab..de8b57b2b62 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -49,6 +49,9 @@ extern int smp_num_siblings;
extern void smp_send_reschedule(int cpu);
extern void zap_low_mappings(void);
void smp_stop_cpu(void);
+extern int smp_call_function_single(int cpuid, void (*func) (void *info),
+ void *info, int retry, int wait);
+
extern cpumask_t cpu_sibling_map[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
extern u8 phys_proc_id[NR_CPUS];