Module Name:    src
Committed By:   rmind
Date:           Mon May  2 00:29:54 UTC 2011

Modified Files:
        src/sys/arch/mips/include: cpu.h
        src/sys/arch/mips/mips: compat_16_machdep.c cpu_subr.c mips_fpu.c
            netbsd32_machdep.c process_machdep.c vm_machdep.c
        src/sys/kern: kern_synch.c subr_pcu.c
        src/sys/sys: pcu.h

Log Message:
Extend PCU:
- Add pcu_ops_t::pcu_state_release() operation for PCU_RELEASE case.
- Add pcu_switchpoint() to perform release operation on context switch.
- Sprinkle const, misc.  Also, sync MIPS with changes.

Per discussions with matt@.


To generate a diff of this commit:
cvs rdiff -u -r1.101 -r1.102 src/sys/arch/mips/include/cpu.h
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/mips/mips/compat_16_machdep.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/mips/mips/mips_fpu.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/mips/mips/netbsd32_machdep.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/mips/mips/process_machdep.c
cvs rdiff -u -r1.137 -r1.138 src/sys/arch/mips/mips/vm_machdep.c
cvs rdiff -u -r1.287 -r1.288 src/sys/kern/kern_synch.c
cvs rdiff -u -r1.3 -r1.4 src/sys/kern/subr_pcu.c
cvs rdiff -u -r1.4 -r1.5 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/include/cpu.h
diff -u src/sys/arch/mips/include/cpu.h:1.101 src/sys/arch/mips/include/cpu.h:1.102
--- src/sys/arch/mips/include/cpu.h:1.101	Thu Apr 14 05:07:30 2011
+++ src/sys/arch/mips/include/cpu.h	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.101 2011/04/14 05:07:30 cliff Exp $	*/
+/*	$NetBSD: cpu.h,v 1.102 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -624,8 +624,7 @@
 void	fpu_discard(void);
 void	fpu_load(void);
 void	fpu_save(void);
-void	fpu_save_lwp(struct lwp *);
-bool	fpu_used_p(struct lwp *);
+bool	fpu_used_p(void);
 
 /* mips_machdep.c */
 void	dumpsys(void);

Index: src/sys/arch/mips/mips/compat_16_machdep.c
diff -u src/sys/arch/mips/mips/compat_16_machdep.c:1.19 src/sys/arch/mips/mips/compat_16_machdep.c:1.20
--- src/sys/arch/mips/mips/compat_16_machdep.c:1.19	Fri Apr 29 22:11:15 2011
+++ src/sys/arch/mips/mips/compat_16_machdep.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_16_machdep.c,v 1.19 2011/04/29 22:11:15 matt Exp $	*/
+/*	$NetBSD: compat_16_machdep.c,v 1.20 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 	
-__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.19 2011/04/29 22:11:15 matt Exp $"); 
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.20 2011/05/02 00:29:54 rmind Exp $"); 
 
 #ifdef _KERNEL_OPT
 #include "opt_cputype.h"
@@ -131,7 +131,7 @@
 #endif
 
 	/* Save the FP state, if necessary, then copy it. */
-	ksc.sc_fpused = fpu_used_p(l);
+	ksc.sc_fpused = fpu_used_p();
 #if !defined(NOFPU)
 	if (ksc.sc_fpused) {
 		/* if FPU has current state, save it first */

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.12 src/sys/arch/mips/mips/cpu_subr.c:1.13
--- src/sys/arch/mips/mips/cpu_subr.c:1.12	Mon May  2 00:17:35 2011
+++ src/sys/arch/mips/mips/cpu_subr.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_subr.c,v 1.12 2011/05/02 00:17:35 matt Exp $	*/
+/*	$NetBSD: cpu_subr.c,v 1.13 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.12 2011/05/02 00:17:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.13 2011/05/02 00:29:54 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -395,7 +395,8 @@
 	*flags |= _UC_CPU | _UC_TLSBASE;
 
 	/* Save floating point register context, if any. */
-	if (fpu_used_p(l)) {
+	KASSERT(l == curlwp);
+	if (fpu_used_p()) {
 		size_t fplen;
 		/*
 		 * If this process is the current FP owner, dump its

Index: src/sys/arch/mips/mips/mips_fpu.c
diff -u src/sys/arch/mips/mips/mips_fpu.c:1.4 src/sys/arch/mips/mips/mips_fpu.c:1.5
--- src/sys/arch/mips/mips/mips_fpu.c:1.4	Fri Apr 29 22:18:16 2011
+++ src/sys/arch/mips/mips/mips_fpu.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_fpu.c,v 1.4 2011/04/29 22:18:16 matt Exp $	*/
+/*	$NetBSD: mips_fpu.c,v 1.5 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_fpu.c,v 1.4 2011/04/29 22:18:16 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_fpu.c,v 1.5 2011/05/02 00:29:54 rmind Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -46,20 +46,26 @@
 #include <mips/regnum.h>
 #include <mips/pcb.h>
 
-static void mips_fpu_state_save(lwp_t *, bool);
+static void mips_fpu_state_save(lwp_t *);
 static void mips_fpu_state_load(lwp_t *, bool);
+static void mips_fpu_state_release(lwp_t *);
 
 static const pcu_ops_t mips_fpu_ops = {
 	.pcu_id = PCU_FPU,
 	.pcu_state_save = mips_fpu_state_save,
 	.pcu_state_load = mips_fpu_state_load,
+	.pcu_state_release = mips_fpu_state_release
+};
+
+/* XXX */
+const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
+	[PCU_FPU] = &mips_fpu_ops
 };
 
 void
 fpu_discard(void)
 {
 	pcu_discard(&mips_fpu_ops);
-	curlwp->l_md.md_utf->tf_regs[_R_SR] &= ~MIPS_SR_COP_1_BIT;
 }
 
 void
@@ -71,23 +77,17 @@
 void
 fpu_save(void)
 {
-	pcu_save_lwp(&mips_fpu_ops, curlwp);
-}
-
-void
-fpu_save_lwp(lwp_t *l)
-{
-	pcu_save_lwp(&mips_fpu_ops, l);
+	pcu_save(&mips_fpu_ops);
 }
 
 bool
-fpu_used_p(lwp_t *l)
+fpu_used_p(void)
 {
-	return pcu_used(&mips_fpu_ops, l);
+	return pcu_used_p(&mips_fpu_ops);
 }
 
 void
-mips_fpu_state_save(lwp_t *l, bool release)
+mips_fpu_state_save(lwp_t *l)
 {
 	struct trapframe * const tf = l->l_md.md_utf;
 	struct pcb * const pcb = lwp_getpcb(l);
@@ -121,13 +121,6 @@
 		"n"(MIPS_COP_0_STATUS));
 
 	/*
-	 * Make sure we don't reenable FP when we return to userspace.
-	 */
-	if (release) {
-		tf->tf_regs[_R_SR] ^= MIPS_SR_COP_1_BIT;
-	}
-
-	/*
 	 * save FPCSR and FP register values.
 	 */
 #if !defined(__mips_o32)
@@ -352,3 +345,11 @@
 	    ::	"r"(fpcsr &~ MIPS_FPU_EXCEPTION_BITS), "r"(status),
 		"n"(MIPS_COP_0_STATUS));
 }
+
+void
+mips_fpu_state_release(lwp_t *l)
+{
+
+	KASSERT(l == curlwp);
+	l->l_md.md_utf->tf_regs[_R_SR] &= ~MIPS_SR_COP_1_BIT;
+}

Index: src/sys/arch/mips/mips/netbsd32_machdep.c
diff -u src/sys/arch/mips/mips/netbsd32_machdep.c:1.6 src/sys/arch/mips/mips/netbsd32_machdep.c:1.7
--- src/sys/arch/mips/mips/netbsd32_machdep.c:1.6	Thu Feb 24 04:28:47 2011
+++ src/sys/arch/mips/mips/netbsd32_machdep.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_machdep.c,v 1.6 2011/02/24 04:28:47 joerg Exp $	*/
+/*	$NetBSD: netbsd32_machdep.c,v 1.7 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.6 2011/02/24 04:28:47 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7 2011/05/02 00:29:54 rmind Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sa.h"
@@ -308,7 +308,8 @@
 		return 0;
 	}
 
-	fpu_save_lwp(l);
+	KASSERT(l == curlwp);
+	fpu_save();
 
 	struct pcb * const pcb = lwp_getpcb(l);
 	cpustate.frame = *l->l_md.md_utf;

Index: src/sys/arch/mips/mips/process_machdep.c
diff -u src/sys/arch/mips/mips/process_machdep.c:1.34 src/sys/arch/mips/mips/process_machdep.c:1.35
--- src/sys/arch/mips/mips/process_machdep.c:1.34	Fri Apr 29 22:09:08 2011
+++ src/sys/arch/mips/mips/process_machdep.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: process_machdep.c,v 1.34 2011/04/29 22:09:08 matt Exp $	*/
+/*	$NetBSD: process_machdep.c,v 1.35 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*
  * Copyright (c) 1993 The Regents of the University of California.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.34 2011/04/29 22:09:08 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.35 2011/05/02 00:29:54 rmind Exp $");
 
 /*
  * This file may seem a bit stylized, but that so that it's easier to port.
@@ -144,7 +144,8 @@
 		*regslen_p = sizeof(struct fpreg_oabi);
 #endif
 
-	fpu_save_lwp(l);
+	KASSERT(l == curlwp);
+	fpu_save();
 	memcpy(regs, &pcb->pcb_fpregs, sizeof(*regs));
 	return 0;
 }

Index: src/sys/arch/mips/mips/vm_machdep.c
diff -u src/sys/arch/mips/mips/vm_machdep.c:1.137 src/sys/arch/mips/mips/vm_machdep.c:1.138
--- src/sys/arch/mips/mips/vm_machdep.c:1.137	Fri Apr 29 22:07:46 2011
+++ src/sys/arch/mips/mips/vm_machdep.c	Mon May  2 00:29:54 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.137 2011/04/29 22:07:46 matt Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.138 2011/05/02 00:29:54 rmind Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.137 2011/04/29 22:07:46 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.138 2011/05/02 00:29:54 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_coredump.h"
@@ -100,7 +100,7 @@
 
 #ifndef NOFPU
 	/* If parent LWP was using FPU, then save the FPU h/w state. */
-	fpu_save_lwp(l1);
+	fpu_save();
 #endif
 
 	/* Copy the PCB from parent. */

Index: src/sys/kern/kern_synch.c
diff -u src/sys/kern/kern_synch.c:1.287 src/sys/kern/kern_synch.c:1.288
--- src/sys/kern/kern_synch.c:1.287	Thu Apr 14 05:33:20 2011
+++ src/sys/kern/kern_synch.c	Mon May  2 00:29:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_synch.c,v 1.287 2011/04/14 05:33:20 matt Exp $	*/
+/*	$NetBSD: kern_synch.c,v 1.288 2011/05/02 00:29:53 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.287 2011/04/14 05:33:20 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.288 2011/05/02 00:29:53 rmind Exp $");
 
 #include "opt_kstack.h"
 #include "opt_perfctrs.h"
@@ -790,6 +790,7 @@
 		 */
 		pmap_activate(l);
 		uvm_emap_switch(l);
+		pcu_switchpoint(l);
 
 		if (prevlwp != NULL) {
 			/* Normalize the count of the spin-mutexes */

Index: src/sys/kern/subr_pcu.c
diff -u src/sys/kern/subr_pcu.c:1.3 src/sys/kern/subr_pcu.c:1.4
--- src/sys/kern/subr_pcu.c:1.3	Sat Feb 19 20:19:54 2011
+++ src/sys/kern/subr_pcu.c	Mon May  2 00:29:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_pcu.c,v 1.3 2011/02/19 20:19:54 matt Exp $	*/
+/*	$NetBSD: subr_pcu.c,v 1.4 2011/05/02 00:29:53 rmind 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.3 2011/02/19 20:19:54 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.4 2011/05/02 00:29:53 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -70,45 +70,79 @@
 #define	PCU_SAVE		0x01	/* Save PCU state to the LWP. */
 #define	PCU_RELEASE		0x02	/* Release PCU state on the CPU. */
 
-#if 0
-/*
- * pcu_init_lwp: initialize PCU structures for LWP.
- */
+/* XXX */
+extern const pcu_ops_t * const	pcu_ops_md_defs[];
+
 void
-pcu_init_lwp(lwp_t *l)
+pcu_switchpoint(lwp_t *l)
 {
+	const uint32_t pcu_inuse = l->l_pcu_used;
+	u_int id;
+	/* int s; */
 
-	memset(l->l_pcu_cpu, 0, sizeof(uint32_t) * PCU_UNIT_COUNT);
-	l->l_pcu_used = 0;
+	KASSERT(l == curlwp);
+
+	if (__predict_true(pcu_inuse == 0)) {
+		/* PCUs are not in use. */
+		return;
+	}
+	/* s = splsoftclock(); */
+	for (id = 0; id < PCU_UNIT_COUNT; id++) {
+		if ((pcu_inuse & (1 << id)) == 0) {
+			continue;
+		}
+		struct cpu_info *pcu_ci = l->l_pcu_cpu[id];
+		if (pcu_ci == NULL || pcu_ci == l->l_cpu) {
+			continue;
+		}
+		const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
+		pcu->pcu_state_release(l);
+	}
+	/* splx(s); */
 }
-#endif
 
 /*
- * pcu_cpu_op: save/release PCU state on the current CPU.
+ * pcu_do_op: save/release PCU state on the current CPU.
  *
  * => Must be called at IPL_SOFTCLOCK or from the soft-interrupt.
  */
-static void
-pcu_cpu_op(const pcu_ops_t *pcu, const int flags)
+static inline void
+pcu_do_op(const pcu_ops_t *pcu, lwp_t * const l, const int flags)
 {
+	struct cpu_info * const ci = curcpu();
 	const u_int id = pcu->pcu_id;
-	struct cpu_info *ci = curcpu();
-	lwp_t *l = ci->ci_pcu_curlwp[id];
 
-	/* If no state - nothing to do. */
-	if (l == NULL) {
-		return;
-	}
+	KASSERT(l->l_cpu == ci);
+
 	if (flags & PCU_SAVE) {
-		pcu->pcu_state_save(l, (flags & PCU_RELEASE) != 0);
+		pcu->pcu_state_save(l);
 	}
 	if (flags & PCU_RELEASE) {
+		pcu->pcu_state_release(l);
 		ci->ci_pcu_curlwp[id] = NULL;
 		l->l_pcu_cpu[id] = NULL;
 	}
 }
 
 /*
+ * pcu_cpu_op: helper routine to call pcu_do_op() via xcall(9).
+ */
+static void
+pcu_cpu_op(const pcu_ops_t *pcu, const int flags)
+{
+	const u_int id = pcu->pcu_id;
+	lwp_t * const l = curcpu()->ci_pcu_curlwp[id];
+
+	KASSERT(cpu_softintr_p());
+
+	/* If no state - nothing to do. */
+	if (l == NULL) {
+		return;
+	}
+	pcu_do_op(pcu, l, flags);
+}
+
+/*
  * pcu_lwp_op: perform PCU state save, release or both operations on LWP.
  */
 static void
@@ -131,14 +165,7 @@
 		 * State is on the current CPU - just perform the operations.
 		 */
 		KASSERT(ci->ci_pcu_curlwp[id] == l);
-
-		if (flags & PCU_SAVE) {
-			pcu->pcu_state_save(l, (flags & PCU_RELEASE) != 0);
-		}
-		if (flags & PCU_RELEASE) {
-			ci->ci_pcu_curlwp[id] = NULL;
-			l->l_pcu_cpu[id] = NULL;
-		}
+		pcu_do_op(pcu, l, flags);
 		splx(s);
 		return;
 	}
@@ -200,7 +227,7 @@
 	KASSERT(l->l_pcu_cpu[id] == NULL);
 
 	/* Save the PCU state on the current CPU, if there is any. */
-	pcu_cpu_op(pcu, PCU_SAVE | PCU_RELEASE);
+	pcu_do_op(pcu, l, PCU_SAVE | PCU_RELEASE);
 	KASSERT(curci->ci_pcu_curlwp[id] == NULL);
 
 	/*
@@ -236,9 +263,10 @@
  * pcu_save_lwp: save PCU state to the given LWP.
  */
 void
-pcu_save_lwp(const pcu_ops_t *pcu, lwp_t *l)
+pcu_save(const pcu_ops_t *pcu)
 {
 	const u_int id = pcu->pcu_id;
+	lwp_t * const l = curlwp;
 
 	KASSERT(!cpu_intr_p() && !cpu_softintr_p());
 
@@ -252,9 +280,10 @@
  * pcu_used: return true if PCU was used (pcu_load() case) by the LWP.
  */
 bool
-pcu_used(const pcu_ops_t *pcu, lwp_t *l)
+pcu_used_p(const pcu_ops_t *pcu)
 {
 	const u_int id = pcu->pcu_id;
+	lwp_t * const l = curlwp;
 
 	return l->l_pcu_used & (1 << id);
 }

Index: src/sys/sys/pcu.h
diff -u src/sys/sys/pcu.h:1.4 src/sys/sys/pcu.h:1.5
--- src/sys/sys/pcu.h:1.4	Sat Feb 19 20:19:54 2011
+++ src/sys/sys/pcu.h	Mon May  2 00:29:53 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcu.h,v 1.4 2011/02/19 20:19:54 matt Exp $	*/
+/*	$NetBSD: pcu.h,v 1.5 2011/05/02 00:29:53 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -32,6 +32,10 @@
 #ifndef _SYS_PCU_H_
 #define _SYS_PCU_H_
 
+#if !defined(_KERNEL)
+#error "not supposed to be exposed to userland"
+#endif
+
 /*
  * Default: no PCU for MD.
  */
@@ -39,19 +43,24 @@
 #define	PCU_UNIT_COUNT		0
 #endif
 
-#if defined(_KERNEL)
+#if PCU_UNIT_COUNT > 0
 
 typedef struct {
 	u_int	pcu_id;
-	void	(*pcu_state_save)(lwp_t *, bool);
+	void	(*pcu_state_save)(lwp_t *);
 	void	(*pcu_state_load)(lwp_t *, bool);
+	void	(*pcu_state_release)(lwp_t *);
 } pcu_ops_t;
 
+void	pcu_switchpoint(lwp_t *);
+
 void	pcu_load(const pcu_ops_t *);
-void	pcu_save_lwp(const pcu_ops_t *, lwp_t *);
+void	pcu_save(const pcu_ops_t *);
 void	pcu_discard(const pcu_ops_t *);
-bool	pcu_used(const pcu_ops_t *, lwp_t *);
+bool	pcu_used_p(const pcu_ops_t *);
 
+#else
+#define	pcu_switchpoint(l)
 #endif
 
 #endif

Reply via email to