Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Deal with PCU state when performing coredumps. As the k...



details:   https://anonhg.NetBSD.org/src/rev/9ae81e2243cc
branches:  trunk
changeset: 766026:9ae81e2243cc
user:      matt <matt%NetBSD.org@localhost>
date:      Mon Jun 13 21:32:42 2011 +0000

description:
Deal with PCU state when performing coredumps.  As the kernel moves each LWP
into LSSUSPENDED state, have that LWP save its PCU state for the coredump and
release its PCU status since its probably going to be exiting very soon.
Make pcu_save_all tolerate for being called for non-curlwp if that lwp belongs
to the same process, has a state of LSSUSPENDED, and no PCUs are in use.

Make the MD coredump code use pcu_save_all(l) since it'll need to save all
the PCU state anyways and can take advantage of the above tests.

diffstat:

 sys/arch/alpha/alpha/core_machdep.c     |   9 ++++-----
 sys/arch/mips/mips/core_machdep.c       |  10 ++++------
 sys/arch/powerpc/powerpc/core_machdep.c |  11 +++--------
 sys/kern/kern_lwp.c                     |  18 ++++++++++--------
 sys/kern/subr_pcu.c                     |  17 +++++++++++++----
 5 files changed, 34 insertions(+), 31 deletions(-)

diffs (198 lines):

diff -r 7517dccda38f -r 9ae81e2243cc sys/arch/alpha/alpha/core_machdep.c
--- a/sys/arch/alpha/alpha/core_machdep.c       Mon Jun 13 21:19:38 2011 +0000
+++ b/sys/arch/alpha/alpha/core_machdep.c       Mon Jun 13 21:32:42 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: core_machdep.c,v 1.5 2011/06/07 00:48:29 matt Exp $ */
+/* $NetBSD: core_machdep.c,v 1.6 2011/06/13 21:32:42 matt Exp $ */
 
 /*
  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.5 2011/06/07 00:48:29 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.6 2011/06/13 21:32:42 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,12 +66,11 @@
                return 0;
        }
 
+       pcu_save_all(l);
        cpustate.md_tf = *l->l_md.md_tf;
        cpustate.md_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp();   /* XXX */
        if (fpu_used_p(l)) {
-               struct pcb *pcb = lwp_getpcb(l);
-               fpu_save();
-               cpustate.md_fpstate = pcb->pcb_fp;
+               cpustate.md_fpstate = ((struct pcb *)lwp_getpcb(l))->pcb_fp;
        } else
                memset(&cpustate.md_fpstate, 0, sizeof(cpustate.md_fpstate));
 
diff -r 7517dccda38f -r 9ae81e2243cc sys/arch/mips/mips/core_machdep.c
--- a/sys/arch/mips/mips/core_machdep.c Mon Jun 13 21:19:38 2011 +0000
+++ b/sys/arch/mips/mips/core_machdep.c Mon Jun 13 21:32:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: core_machdep.c,v 1.5 2011/02/20 07:45:47 matt Exp $    */
+/*     $NetBSD: core_machdep.c,v 1.6 2011/06/13 21:32:42 matt Exp $    */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.5 2011/02/20 07:45:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.6 2011/06/13 21:32:42 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,7 +67,6 @@
 cpu_coredump(struct lwp *l, void *iocookie, struct core *chdr)
 {
        int error;
-       struct pcb *pcb;
        struct coreseg cseg;
        struct cpustate {
                struct trapframe tf;
@@ -83,10 +82,9 @@
                return 0;
        }
 
-       fpu_save();
-       pcb = lwp_getpcb(l);
+       pcu_save_all(l);
        cpustate.tf = *l->l_md.md_utf;
-       cpustate.fpregs = pcb->pcb_fpregs;
+       cpustate.fpregs = ((struct pcb *)lwp_getpcb(l))->pcb_fpregs;
 
        CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
        cseg.c_addr = 0;
diff -r 7517dccda38f -r 9ae81e2243cc sys/arch/powerpc/powerpc/core_machdep.c
--- a/sys/arch/powerpc/powerpc/core_machdep.c   Mon Jun 13 21:19:38 2011 +0000
+++ b/sys/arch/powerpc/powerpc/core_machdep.c   Mon Jun 13 21:32:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: core_machdep.c,v 1.7 2011/05/02 02:01:33 matt Exp $    */
+/*     $NetBSD: core_machdep.c,v 1.8 2011/06/13 21:32:43 matt Exp $    */
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.7 2011/05/02 02:01:33 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.8 2011/06/13 21:32:43 matt Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altivec.h"
@@ -77,19 +77,14 @@
        }
 
        md_core.frame = *l->l_md.md_utf;
+       pcu_save_all(l);
        if (fpu_used_p(l)) {
-#ifdef PPC_HAVE_FPU
-               KASSERT(l == curlwp);
-               fpu_save();
-#endif
                md_core.fpstate = pcb->pcb_fpu;
        } else
                memset(&md_core.fpstate, 0, sizeof(md_core.fpstate));
 
 #if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
        if (vec_used_p(l)) {
-               KASSERT(l == curlwp);
-               vec_save();
                md_core.vstate = pcb->pcb_vr;
        } else
 #endif
diff -r 7517dccda38f -r 9ae81e2243cc sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Mon Jun 13 21:19:38 2011 +0000
+++ b/sys/kern/kern_lwp.c       Mon Jun 13 21:32:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.158 2011/06/06 22:04:34 matt Exp $      */
+/*     $NetBSD: kern_lwp.c,v 1.159 2011/06/13 21:32:42 matt Exp $      */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.158 2011/06/06 22:04:34 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.159 2011/06/13 21:32:42 matt Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -1395,14 +1395,16 @@
                /*
                 * Core-dump or suspend pending.
                 *
-                * In case of core dump, suspend ourselves, so that the
-                * kernel stack and therefore the userland registers saved
-                * in the trapframe are around for coredump() to write them
-                * out.  We issue a wakeup on p->p_lwpcv so that sigexit()
-                * will write the core file out once all other LWPs are
-                * suspended.
+                * In case of core dump, suspend ourselves, so that the kernel
+                * stack and therefore the userland registers saved in the
+                * trapframe are around for coredump() to write them out.
+                * We also need to save any PCU resources that we have so that
+                * they accessible for coredump().  We issue a wakeup on
+                * p->p_lwpcv so that sigexit() will write the core file out
+                * once all other LWPs are suspended.  
                 */
                if ((l->l_flag & LW_WSUSPEND) != 0) {
+                       pcu_save_all(l);
                        mutex_enter(p->p_lock);
                        p->p_nrlwps--;
                        cv_broadcast(&p->p_lwpcv);
diff -r 7517dccda38f -r 9ae81e2243cc sys/kern/subr_pcu.c
--- a/sys/kern/subr_pcu.c       Mon Jun 13 21:19:38 2011 +0000
+++ b/sys/kern/subr_pcu.c       Mon Jun 13 21:32:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_pcu.c,v 1.8 2011/06/07 17:51:58 matt Exp $        */
+/*     $NetBSD: subr_pcu.c,v 1.9 2011/06/13 21:32:42 matt Exp $        */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.8 2011/06/07 17:51:58 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.9 2011/06/13 21:32:42 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -137,8 +137,17 @@
 pcu_save_all(lwp_t *l)
 {
        const uint32_t pcu_inuse = l->l_pcu_used;
+       const int flags = PCU_SAVE | (l->l_flag & LW_WCORE ? PCU_RELEASE : 0);
 
-       KASSERT(l == curlwp || ((l->l_flag & LW_SYSTEM) && pcu_inuse == 0));
+       /*
+        * Normally we save for the current LWP, but sometimes we get called
+        * with a different LWP (forking a system LWP or doing a coredump of
+        * a process with multiple threads) and we need to deal with that.
+        */
+       KASSERT(l == curlwp
+           || (((l->l_flag & LW_SYSTEM)
+                || (curlwp->l_proc == l->l_proc && l->l_stat == LSSUSPENDED))
+               && pcu_inuse == 0));
 
        if (__predict_true(pcu_inuse == 0)) {
                /* PCUs are not in use. */
@@ -157,7 +166,7 @@
                 * We aren't releasing since this LWP isn't giving up PCU,
                 * just saving it.
                 */
-               pcu_lwp_op(pcu, l, PCU_SAVE);
+               pcu_lwp_op(pcu, l, flags);
        }
        splx(s);
 }



Home | Main Index | Thread Index | Old Index