Module Name:    src
Committed By:   matt
Date:           Mon Jun  6 22:04:35 UTC 2011

Modified Files:
        src/sys/arch/mips/mips: vm_machdep.c
        src/sys/arch/powerpc/powerpc: vm_machdep.c
        src/sys/kern: kern_exec.c kern_exit.c kern_lwp.c subr_pcu.c
        src/sys/sys: pcu.h

Log Message:
Add some more MI hook points for PCU.  Discard the PCU state at lwp_exit and
at exec time.  Before forking, save the PCU state so that cpu_lwp_fork
doesn't have.  Remove MD code which did that before.


To generate a diff of this commit:
cvs rdiff -u -r1.138 -r1.139 src/sys/arch/mips/mips/vm_machdep.c
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/powerpc/powerpc/vm_machdep.c
cvs rdiff -u -r1.315 -r1.316 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.233 -r1.234 src/sys/kern/kern_exit.c
cvs rdiff -u -r1.157 -r1.158 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.6 -r1.7 src/sys/kern/subr_pcu.c
cvs rdiff -u -r1.7 -r1.8 src/sys/sys/pcu.h

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/mips/mips/vm_machdep.c
diff -u src/sys/arch/mips/mips/vm_machdep.c:1.138 src/sys/arch/mips/mips/vm_machdep.c:1.139
--- src/sys/arch/mips/mips/vm_machdep.c:1.138	Mon May  2 00:29:54 2011
+++ src/sys/arch/mips/mips/vm_machdep.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.138 2011/05/02 00:29:54 rmind Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.139 2011/06/06 22:04:34 matt Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.138 2011/05/02 00:29:54 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.139 2011/06/06 22:04:34 matt Exp $");
 
 #include "opt_ddb.h"
 #include "opt_coredump.h"
@@ -98,11 +98,6 @@
 	l2->l_md.md_ss_instr = 0;
 	l2->l_md.md_astpending = 0;
 
-#ifndef NOFPU
-	/* If parent LWP was using FPU, then save the FPU h/w state. */
-	fpu_save();
-#endif
-
 	/* Copy the PCB from parent. */
 	*pcb2 = *pcb1;
 
@@ -260,9 +255,8 @@
 void
 cpu_lwp_free(struct lwp *l, int proc)
 {
-	KASSERT(l == curlwp);
 
-	fpu_discard();
+	(void)l;
 }
 
 vaddr_t

Index: src/sys/arch/powerpc/powerpc/vm_machdep.c
diff -u src/sys/arch/powerpc/powerpc/vm_machdep.c:1.84 src/sys/arch/powerpc/powerpc/vm_machdep.c:1.85
--- src/sys/arch/powerpc/powerpc/vm_machdep.c:1.84	Mon May  2 02:01:33 2011
+++ src/sys/arch/powerpc/powerpc/vm_machdep.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.84 2011/05/02 02:01:33 matt Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.85 2011/06/06 22:04:34 matt Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.84 2011/05/02 02:01:33 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.85 2011/06/06 22:04:34 matt Exp $");
 
 #include "opt_altivec.h"
 #include "opt_multiprocessor.h"
@@ -92,13 +92,6 @@
 	struct pcb * const pcb1 = lwp_getpcb(l1);
 	struct pcb * const pcb2 = lwp_getpcb(l2);
 
-#ifdef PPC_HAVE_FPU
-	fpu_save();
-#endif
-#if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
-	vec_save();
-#endif
-
 	/* Copy MD part of lwp and set up user trapframe pointer.  */
 	l2->l_md = l1->l_md;
 	l2->l_md.md_utf = trapframe(l2);
@@ -167,16 +160,8 @@
 void
 cpu_lwp_free(struct lwp *l, int proc)
 {
-	KASSERT(l == curlwp);
-#ifdef PPC_HAVE_FPU
-	/* release the FPU */
-	fpu_discard();
-#endif
-#if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
-	/* release the vector unit */
-	vec_discard();
-#endif
 
+	(void)l;
 }
 
 void

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.315 src/sys/kern/kern_exec.c:1.316
--- src/sys/kern/kern_exec.c:1.315	Wed Jun  1 21:24:59 2011
+++ src/sys/kern/kern_exec.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.315 2011/06/01 21:24:59 alnsn Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.316 2011/06/06 22:04:34 matt Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.315 2011/06/01 21:24:59 alnsn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.316 2011/06/06 22:04:34 matt Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_modular.h"
@@ -1109,6 +1109,9 @@
 	/* Provide a consistent LWP private setting */
 	(void)lwp_setprivate(l, NULL);
 
+	/* Discard all PCU state; need to start fresh */
+	pcu_discard_all(l);
+
 	/* map the process's signal trampoline code */
 	if ((error = exec_sigcode_map(p, pack.ep_esch->es_emul)) != 0) {
 		DPRINTF(("%s: map sigcode failed %d\n", __func__, error));

Index: src/sys/kern/kern_exit.c
diff -u src/sys/kern/kern_exit.c:1.233 src/sys/kern/kern_exit.c:1.234
--- src/sys/kern/kern_exit.c:1.233	Sun May  1 00:11:52 2011
+++ src/sys/kern/kern_exit.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exit.c,v 1.233 2011/05/01 00:11:52 rmind Exp $	*/
+/*	$NetBSD: kern_exit.c,v 1.234 2011/06/06 22:04:34 matt Exp $	*/
 
 /*-
  * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.233 2011/05/01 00:11:52 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.234 2011/06/06 22:04:34 matt Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_perfctrs.h"
@@ -534,6 +534,11 @@
 	callout_destroy(&l->l_timeout_ch);
 
 	/*
+	 * Release any PCU resources before becoming a zombie.
+	 */
+	pcu_discard_all(l);
+
+	/*
 	 * Remaining lwp resources will be freed in lwp_exit2() once we've
 	 * switch to idle context; at that point, we will be marked as a
 	 * full blown zombie.

Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.157 src/sys/kern/kern_lwp.c:1.158
--- src/sys/kern/kern_lwp.c:1.157	Sun Mar 20 23:19:16 2011
+++ src/sys/kern/kern_lwp.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lwp.c,v 1.157 2011/03/20 23:19:16 rmind Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.158 2011/06/06 22:04:34 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.157 2011/03/20 23:19:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.158 2011/06/06 22:04:34 matt Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -762,6 +762,12 @@
 	if (rnewlwpp != NULL)
 		*rnewlwpp = l2;
 
+	/*
+	 * PCU state needs to be saved before calling uvm_lwp_fork() so that
+	 * the MD cpu_lwp_fork() can copy the saved state to the new LWP.
+	 */
+	pcu_save_all(l1);
+
 	uvm_lwp_setuarea(l2, uaddr);
 	uvm_lwp_fork(l1, l2, stack, stacksize, func,
 	    (arg != NULL) ? arg : l2);
@@ -969,6 +975,11 @@
 		}
 	}
 
+	/*
+	 * Release any PCU resources before becoming a zombie.
+	 */
+	pcu_discard_all(l);
+
 	lwp_lock(l);
 	l->l_stat = LSZOMB;
 	if (l->l_name != NULL)

Index: src/sys/kern/subr_pcu.c
diff -u src/sys/kern/subr_pcu.c:1.6 src/sys/kern/subr_pcu.c:1.7
--- src/sys/kern/subr_pcu.c:1.6	Mon May  2 06:33:16 2011
+++ src/sys/kern/subr_pcu.c	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_pcu.c,v 1.6 2011/05/02 06:33:16 matt Exp $	*/
+/*	$NetBSD: subr_pcu.c,v 1.7 2011/06/06 22:04:34 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.6 2011/05/02 06:33:16 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.7 2011/06/06 22:04:34 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -67,6 +67,8 @@
 
 #if PCU_UNIT_COUNT > 0
 
+static void pcu_lwp_op(const pcu_ops_t *, lwp_t *, int);
+
 #define	PCU_SAVE		0x01	/* Save PCU state to the LWP. */
 #define	PCU_RELEASE		0x02	/* Release PCU state on the CPU. */
 
@@ -101,6 +103,65 @@
 	/* splx(s); */
 }
 
+void
+pcu_discard_all(lwp_t *l)
+{
+	const uint32_t pcu_inuse = l->l_pcu_used;
+
+	KASSERT(l == curlwp);
+
+	if (__predict_true(pcu_inuse == 0)) {
+		/* PCUs are not in use. */
+		return;
+	}
+	const int s = splsoftclock();
+	for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
+		if ((pcu_inuse & (1 << id)) == 0) {
+			continue;
+		}
+		if (__predict_true(l->l_pcu_cpu[id] == NULL)) {
+			continue;
+		}
+		const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
+		/*
+		 * We aren't releasing since this LWP isn't giving up PCU,
+		 * just saving it.
+		 */
+		pcu_lwp_op(pcu, l, PCU_RELEASE);
+	}
+	l->l_pcu_used = 0;
+	splx(s);
+}
+
+void
+pcu_save_all(lwp_t *l)
+{
+	const uint32_t pcu_inuse = l->l_pcu_used;
+
+	KASSERT(l == curlwp);
+
+	if (__predict_true(pcu_inuse == 0)) {
+		/* PCUs are not in use. */
+		return;
+	}
+	const int s = splsoftclock();
+	for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
+		if ((pcu_inuse & (1 << id)) == 0) {
+			continue;
+		}
+		if (__predict_true(l->l_pcu_cpu[id] == NULL)) {
+			continue;
+		}
+		const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
+		/*
+		 * We aren't releasing since this LWP isn't giving up PCU,
+		 * just saving it.
+		 */
+		pcu_lwp_op(pcu, l, PCU_SAVE);
+	}
+	splx(s);
+}
+
 /*
  * pcu_do_op: save/release PCU state on the current CPU.
  *
@@ -112,7 +173,7 @@
 	struct cpu_info * const ci = curcpu();
 	const u_int id = pcu->pcu_id;
 
-	KASSERT(l->l_cpu == ci);
+	KASSERT(l->l_pcu_cpu[id] == ci);
 
 	if (flags & PCU_SAVE) {
 		pcu->pcu_state_save(l);

Index: src/sys/sys/pcu.h
diff -u src/sys/sys/pcu.h:1.7 src/sys/sys/pcu.h:1.8
--- src/sys/sys/pcu.h:1.7	Mon May  2 08:26:32 2011
+++ src/sys/sys/pcu.h	Mon Jun  6 22:04:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcu.h,v 1.7 2011/05/02 08:26:32 martin Exp $	*/
+/*	$NetBSD: pcu.h,v 1.8 2011/06/06 22:04:34 matt Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -57,6 +57,8 @@
 } pcu_ops_t;
 
 void	pcu_switchpoint(lwp_t *);
+void	pcu_discard_all(lwp_t *);
+void	pcu_save_all(lwp_t *);
 
 void	pcu_load(const pcu_ops_t *);
 void	pcu_save(const pcu_ops_t *);
@@ -65,6 +67,8 @@
 
 #else
 #define	pcu_switchpoint(l)
+#define	pcu_discard_all(l)
+#define	pcu_save_all(l)
 #endif
 
 #endif

Reply via email to