aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/mca_asm.S
diff options
context:
space:
mode:
authorRuss Anderson <rja@sgi.com>2007-05-18 18:17:17 -0400
committerTony Luck <tony.luck@intel.com>2007-07-11 14:50:11 -0400
commit1612b18ccb2318563ba51268289dc3271a6052f7 (patch)
tree65e809216e33ddd35aad274eabb159b8c56edf1c /arch/ia64/kernel/mca_asm.S
parent256a7e097ba3d1179867b4c9aba1b75fb32d44f2 (diff)
[IA64] Support multiple CPUs going through OS_MCA
Linux does not gracefully deal with multiple processors going through OS_MCA aa part of the same MCA event. The first cpu into OS_MCA grabs the ia64_mca_serialize lock. Subsequent cpus wait for that lock, preventing them from reporting in as rendezvoused. The first cpu waits 5 seconds then complains that all the cpus have not rendezvoused. The first cpu then handles its MCA and frees up all the rendezvoused cpus and releases the ia64_mca_serialize lock. One of the subsequent cpus going thought OS_MCA then gets the ia64_mca_serialize lock, waits another 5 seconds and then complains that none of the other cpus have rendezvoused. This patch allows multiple CPUs to gracefully go through OS_MCA. The first CPU into ia64_mca_handler() grabs a mca_count lock. Subsequent CPUs into ia64_mca_handler() are added to a list of cpus that need to go through OS_MCA (a bit set in mca_cpu), and report in as rendezvoused, and but spin waiting their turn. The first CPU sees everyone rendezvous, handles his MCA, wakes up one of the other CPUs waiting to process their MCA (by clearing one mca_cpu bit), and then waits for the other cpus to complete their MCA handling. The next CPU handles his MCA and the process repeats until all the CPUs have handled their MCA. When the last CPU has handled it's MCA, it sets monarch_cpu to -1, releasing all the CPUs. In testing this works more reliably and faster. Thanks to Keith Owens for suggesting numerous improvements to this code. Signed-off-by: Russ Anderson <rja@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/mca_asm.S')
-rw-r--r--arch/ia64/kernel/mca_asm.S12
1 files changed, 0 insertions, 12 deletions
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 8c9c26aa6ae0..0f5965fcdf85 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -133,14 +133,6 @@ ia64_do_tlb_purge:
133//StartMain//////////////////////////////////////////////////////////////////// 133//StartMain////////////////////////////////////////////////////////////////////
134 134
135ia64_os_mca_dispatch: 135ia64_os_mca_dispatch:
136 // Serialize all MCA processing
137 mov r3=1;;
138 LOAD_PHYSICAL(p0,r2,ia64_mca_serialize);;
139ia64_os_mca_spin:
140 xchg4 r4=[r2],r3;;
141 cmp.ne p6,p0=r4,r0
142(p6) br ia64_os_mca_spin
143
144 mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack 136 mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack
145 LOAD_PHYSICAL(p0,r2,1f) // return address 137 LOAD_PHYSICAL(p0,r2,1f) // return address
146 mov r19=1 // All MCA events are treated as monarch (for now) 138 mov r19=1 // All MCA events are treated as monarch (for now)
@@ -291,10 +283,6 @@ END(ia64_os_mca_virtual_begin)
291 283
292 mov b0=r12 // SAL_CHECK return address 284 mov b0=r12 // SAL_CHECK return address
293 285
294 // release lock
295 LOAD_PHYSICAL(p0,r3,ia64_mca_serialize);;
296 st4.rel [r3]=r0
297
298 br b0 286 br b0
299 287
300//EndMain////////////////////////////////////////////////////////////////////// 288//EndMain//////////////////////////////////////////////////////////////////////