Index: sparc/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v retrieving revision 1.225 diff -p -r1.225 cpu.c *** sparc/cpu.c 22 Jan 2011 12:13:25 -0000 1.225 --- sparc/cpu.c 26 Jan 2011 06:09:54 -0000 *************** xcall(xcall_func_t func, xcall_trap_t tr *** 583,588 **** --- 583,589 ---- volatile struct xpmsg_func *p; int fasttrap; int is_noop = func == (xcall_func_t)sparc_noop; + u_int failed_cpuset; mybit = (1 << cpuinfo.ci_cpuid); callself = func && (cpuset & mybit) != 0; *************** xcall(xcall_func_t func, xcall_trap_t tr *** 632,650 **** done = is_noop; i = 100000; /* time-out, not too long, but still an _AGE_ */ while (!done) { - if (--i < 0) { - printf_nolog("xcall(cpu%d,%p): couldn't ping cpus:", - cpu_number(), func); - } done = 1; for (CPU_INFO_FOREACH(n, cpi)) { if ((cpuset & (1 << n)) == 0) continue; if (cpi->msg.complete == 0) { if (i < 0) { ! printf_nolog(" cpu%d", cpi->ci_cpuid); } else { done = 0; break; --- 633,648 ---- done = is_noop; i = 100000; /* time-out, not too long, but still an _AGE_ */ while (!done) { done = 1; + failed_cpuset = 0; for (CPU_INFO_FOREACH(n, cpi)) { if ((cpuset & (1 << n)) == 0) continue; if (cpi->msg.complete == 0) { if (i < 0) { ! failed_cpuset |= (1 << n); } else { done = 0; break; *************** xcall(xcall_func_t func, xcall_trap_t tr *** 652,661 **** } } } - if (i < 0) - printf_nolog("\n"); mutex_spin_exit(&xpmsg_mutex); } /* --- 650,674 ---- } } } mutex_spin_exit(&xpmsg_mutex); + + + /* + * Ping the failed xcall(), see if they can tell us what they + * were doing. + */ + if (i < 0) { + for (CPU_INFO_FOREACH(n, cpi)) + if (failed_cpuset & (1 << n)) + mp_ping_cpu(cpi); + printf_nolog("xcall(cpu%d,%p): couldn't ping cpus:", + cpu_number(), func); + for (CPU_INFO_FOREACH(n, cpi)) + if (failed_cpuset & (1 << n)) + printf_nolog(" cpu%d", cpi->ci_cpuid); + printf_nolog("\n"); + } } /* *************** mp_resume_cpus_ddb(void) *** 782,787 **** --- 795,812 ---- } } #endif /* DDB */ + + /* + * ping the remote CPU with a highest priority interrupt, used + * when we had an IPI timeout. + */ + void + mp_ping_cpu(struct cpu_info *cpi) + { + + cpi->msg_lev15.tag = XPMSG15_PING; + raise_ipi(cpi,15); /* high priority intr */ + } #endif /* MULTIPROCESSOR */ /* Index: sparc/cpuvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpuvar.h,v retrieving revision 1.84 diff -p -r1.84 cpuvar.h *** sparc/cpuvar.h 13 Jan 2011 05:20:27 -0000 1.84 --- sparc/cpuvar.h 26 Jan 2011 06:09:54 -0000 *************** struct xpmsg { *** 96,101 **** --- 96,102 ---- #define XPMSG15_PAUSECPU 1 #define XPMSG_FUNC 4 #define XPMSG_FTRP 5 + #define XPMSG15_PING 6 volatile union { /* *************** extern int bootmid; /* Module ID of bo *** 488,493 **** --- 489,495 ---- extern struct cpu_info *cpus[]; #ifdef MULTIPROCESSOR extern u_int cpu_ready_mask; /* the set of CPUs marked as READY */ + void mp_ping_cpu(struct cpu_info *cpi); /* are you alive? */ #endif #define cpuinfo (*(struct cpu_info *)CPUINFO_VA) Index: sparc/intr.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/intr.c,v retrieving revision 1.109 diff -p -r1.109 intr.c *** sparc/intr.c 22 Jan 2011 10:37:22 -0000 1.109 --- sparc/intr.c 26 Jan 2011 06:09:54 -0000 *************** nmi_soft(struct trapframe *tf) *** 369,374 **** --- 369,384 ---- while (cpuinfo.flags & CPUFLG_PAUSED) /* spin */; #endif /* DDB */ + break; + + case XPMSG15_PING: + /* XXX printf_nolog() at IPL 15? */ + printf_nolog("cpu%d: ping while pc/npc %#x/%#x psr %#x" + " %%o7 %#x\n", cpu_number(), + tf->tf_pc, tf->tf_npc, tf->tf_psr, + tf->tf_out[7]); + break; + } cpuinfo.msg_lev15.tag = 0; #endif /* MULTIPROCESSOR */ Index: sparc/locore.s =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/locore.s,v retrieving revision 1.259 diff -p -r1.259 locore.s *** sparc/locore.s 13 Jan 2011 05:20:27 -0000 1.259 --- sparc/locore.s 26 Jan 2011 06:09:54 -0000 *************** _ENTRY(_C_LABEL(nmi_sun4m)) *** 3092,3103 **** 1: #if defined(MULTIPROCESSOR) && defined(DDB) /* ! * Setup a trapframe for nmi_soft; this might be an IPI telling ! * us to pause, so lets save some state for DDB to get at. */ - std %l0, [%sp + CCFSZ] ! tf.tf_psr = psr; tf.tf_pc = ret_pc; rd %y, %l3 std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc = return_npc; tf.tf_y = %y; st %g1, [%sp + CCFSZ + 20] std %g2, [%sp + CCFSZ + 24] std %g4, [%sp + CCFSZ + 32] --- 3092,3105 ---- 1: #if defined(MULTIPROCESSOR) && defined(DDB) /* ! * Setup a trapframe for nmi_soft; this might be an IPI telling us ! * to pause or ping, so lets save some state for them to get at. */ rd %y, %l3 + std %l0, [%sp + CCFSZ] ! tf.tf_psr = psr; tf.tf_pc = ret_pc; + rd %wim, %l4 std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc = return_npc; tf.tf_y = %y; + st %l4, [%sp + CCFSZ + 16] ! tf.tf_global[0] = %wim st %g1, [%sp + CCFSZ + 20] std %g2, [%sp + CCFSZ + 24] std %g4, [%sp + CCFSZ + 32]