Module Name:    src
Committed By:   matt
Date:           Mon Jun 13 21:32:43 UTC 2011

Modified Files:
        src/sys/arch/alpha/alpha: core_machdep.c
        src/sys/arch/mips/mips: core_machdep.c
        src/sys/arch/powerpc/powerpc: core_machdep.c
        src/sys/kern: kern_lwp.c subr_pcu.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/alpha/alpha/core_machdep.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/mips/mips/core_machdep.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/powerpc/powerpc/core_machdep.c
cvs rdiff -u -r1.158 -r1.159 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.8 -r1.9 src/sys/kern/subr_pcu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/alpha/alpha/core_machdep.c
diff -u src/sys/arch/alpha/alpha/core_machdep.c:1.5 src/sys/arch/alpha/alpha/core_machdep.c:1.6
--- src/sys/arch/alpha/alpha/core_machdep.c:1.5	Tue Jun  7 00:48:29 2011
+++ src/sys/arch/alpha/alpha/core_machdep.c	Mon Jun 13 21:32:42 2011
@@ -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));
 

Index: src/sys/arch/mips/mips/core_machdep.c
diff -u src/sys/arch/mips/mips/core_machdep.c:1.5 src/sys/arch/mips/mips/core_machdep.c:1.6
--- src/sys/arch/mips/mips/core_machdep.c:1.5	Sun Feb 20 07:45:47 2011
+++ src/sys/arch/mips/mips/core_machdep.c	Mon Jun 13 21:32:42 2011
@@ -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;

Index: src/sys/arch/powerpc/powerpc/core_machdep.c
diff -u src/sys/arch/powerpc/powerpc/core_machdep.c:1.7 src/sys/arch/powerpc/powerpc/core_machdep.c:1.8
--- src/sys/arch/powerpc/powerpc/core_machdep.c:1.7	Mon May  2 02:01:33 2011
+++ src/sys/arch/powerpc/powerpc/core_machdep.c	Mon Jun 13 21:32:43 2011
@@ -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

Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.158 src/sys/kern/kern_lwp.c:1.159
--- src/sys/kern/kern_lwp.c:1.158	Mon Jun  6 22:04:34 2011
+++ src/sys/kern/kern_lwp.c	Mon Jun 13 21:32:42 2011
@@ -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);

Index: src/sys/kern/subr_pcu.c
diff -u src/sys/kern/subr_pcu.c:1.8 src/sys/kern/subr_pcu.c:1.9
--- src/sys/kern/subr_pcu.c:1.8	Tue Jun  7 17:51:58 2011
+++ src/sys/kern/subr_pcu.c	Mon Jun 13 21:32:42 2011
@@ -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);
 }

Reply via email to