Author: neel
Date: Thu Mar 11 07:17:14 2010
New Revision: 204997
URL: http://svn.freebsd.org/changeset/base/204997

Log:
  Stash the context of the running thread at the time an IPI_STOP is received
  in 'stoppcbs[]'. We use the 'stoppcbs[]' context to generate the backtrace
  of such stopped threads.

Modified:
  head/sys/mips/include/kdb.h
  head/sys/mips/include/smp.h
  head/sys/mips/mips/db_trace.c
  head/sys/mips/mips/mp_machdep.c
  head/sys/mips/mips/swtch.S

Modified: head/sys/mips/include/kdb.h
==============================================================================
--- head/sys/mips/include/kdb.h Thu Mar 11 03:18:16 2010        (r204996)
+++ head/sys/mips/include/kdb.h Thu Mar 11 07:17:14 2010        (r204997)
@@ -32,6 +32,8 @@
 
 #include <machine/frame.h>
 
+#define        KDB_STOPPEDPCB(pc)      &stoppcbs[pc->pc_cpuid]
+
 static __inline void
 kdb_cpu_clear_singlestep(void)
 {

Modified: head/sys/mips/include/smp.h
==============================================================================
--- head/sys/mips/include/smp.h Thu Mar 11 03:18:16 2010        (r204996)
+++ head/sys/mips/include/smp.h Thu Mar 11 07:17:14 2010        (r204997)
@@ -17,6 +17,8 @@
 
 #ifdef _KERNEL
 
+#include <machine/pcb.h>
+
 /*
  * Interprocessor interrupts for SMP.
  */
@@ -31,6 +33,8 @@ void  ipi_selected(cpumask_t cpus, int ip
 void   smp_init_secondary(u_int32_t cpuid);
 void   mpentry(void);
 
+extern struct pcb stoppcbs[];
+
 #endif /* !LOCORE */
 #endif /* _KERNEL */
 

Modified: head/sys/mips/mips/db_trace.c
==============================================================================
--- head/sys/mips/mips/db_trace.c       Thu Mar 11 03:18:16 2010        
(r204996)
+++ head/sys/mips/mips/db_trace.c       Thu Mar 11 07:17:14 2010        
(r204997)
@@ -169,6 +169,12 @@ loop:
                subr = (uintptr_t)MipsKernTLBInvalidException;
        else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException))
                subr = (uintptr_t)MipsUserTLBInvalidException;
+       else if (pcBetween(fork_trampoline, savectx))
+               subr = (uintptr_t)fork_trampoline;
+       else if (pcBetween(savectx, mips_cpu_throw))
+               subr = (uintptr_t)savectx;
+       else if (pcBetween(mips_cpu_throw, cpu_switch))
+               subr = (uintptr_t)cpu_throw;
        else if (pcBetween(cpu_switch, MipsSwitchFPState))
                subr = (uintptr_t)cpu_switch;
        else if (pcBetween(_locore, _locoreEnd)) {
@@ -412,10 +418,8 @@ db_trace_thread(struct thread *thr, int 
                          : "=r" (pc)
                         : "r" (ra));
 
-       }
-
-       else {
-               ctx = thr->td_pcb;
+       } else {
+               ctx = kdb_thr_ctx(thr);
                sp = (register_t)ctx->pcb_context[PREG_SP];
                pc = (register_t)ctx->pcb_context[PREG_PC];
                ra = (register_t)ctx->pcb_context[PREG_RA];

Modified: head/sys/mips/mips/mp_machdep.c
==============================================================================
--- head/sys/mips/mips/mp_machdep.c     Thu Mar 11 03:18:16 2010        
(r204996)
+++ head/sys/mips/mips/mp_machdep.c     Thu Mar 11 07:17:14 2010        
(r204997)
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr_machdep.h>
 #include <machine/cache.h>
 
+struct pcb stoppcbs[MAXCPU];
+
 static void *dpcpu;
 static struct mtx ap_boot_mtx;
 
@@ -88,10 +90,14 @@ ipi_selected(cpumask_t cpus, int ipi)
 static int
 mips_ipi_handler(void *arg)
 {
+       int cpu;
        cpumask_t cpumask;
        u_int   ipi, ipi_bitmap;
        int     bit;
 
+       cpu = PCPU_GET(cpuid);
+       cpumask = PCPU_GET(cpumask);
+
        platform_ipi_clear();   /* quiesce the pending ipi interrupt */
 
        ipi_bitmap = atomic_readandclear_int(PCPU_PTR(pending_ipis));
@@ -120,10 +126,16 @@ mips_ipi_handler(void *arg)
                         * necessary to add it in the switch.
                         */
                        CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD");
-                       cpumask = PCPU_GET(cpumask);
+
+                       savectx(&stoppcbs[cpu]);
+
+                       /* Indicate we are stopped */
                        atomic_set_int(&stopped_cpus, cpumask);
+
+                       /* Wait for restart */
                        while ((started_cpus & cpumask) == 0)
                                cpu_spinwait();
+
                        atomic_clear_int(&started_cpus, cpumask);
                        atomic_clear_int(&stopped_cpus, cpumask);
                        CTR0(KTR_SMP, "IPI_STOP (restart)");

Modified: head/sys/mips/mips/swtch.S
==============================================================================
--- head/sys/mips/mips/swtch.S  Thu Mar 11 03:18:16 2010        (r204996)
+++ head/sys/mips/mips/swtch.S  Thu Mar 11 07:17:14 2010        (r204997)
@@ -245,6 +245,14 @@ LEAF(savectx)
        SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)
        SAVE_U_PCB_CONTEXT(v0, PREG_SR, a0)
        SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
+
+       move    v0, ra                  /* save 'ra' before we trash it */
+       jal     1f
+       nop
+1:
+       SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0)
+       move    ra, v0                  /* restore 'ra' before returning */
+
        /*
         * FREEBSD_DEVELOPERS_FIXME:
         * In case there are CPU-specific registers that need
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to