Module Name:    src
Committed By:   drochner
Date:           Thu Aug 22 19:50:55 UTC 2013

Modified Files:
        src/sys/arch/alpha/include: alpha.h
        src/sys/arch/arm/vfp: vfp_init.c
        src/sys/arch/mips/mips: mips_dsp.c mips_fpu.c
        src/sys/arch/powerpc/include: altivec.h fpu.h
        src/sys/arch/powerpc/oea: altivec.c
        src/sys/arch/powerpc/powerpc: fpu.c
        src/sys/kern: kern_cpu.c subr_pcu.c
        src/sys/sys: pcu.h

Log Message:
-extend the pcu(9) API by a function which saves all context on the
 current CPU, and use it if a CPU is taken offline
-add a bool argument to pcu_discard which tells whether the internal
 "LWP has used the coprocessor" flag should be set or reset. The flag
 is reported by pcu_used_p(). If set, future accesses should use the
 state stored in the PCB. If reset, it should be reset to default.
 The former case is useful for setmcontext().
 With that, it should not be necessary anymore to manage the "FPU used"
 state by an additional MD variable.

approved by matt


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/alpha/include/alpha.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/arm/vfp/vfp_init.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/mips/mips/mips_dsp.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/mips/mips/mips_fpu.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/powerpc/include/altivec.h
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/powerpc/include/fpu.h
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/powerpc/oea/altivec.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/powerpc/powerpc/fpu.c
cvs rdiff -u -r1.59 -r1.60 src/sys/kern/kern_cpu.c
cvs rdiff -u -r1.14 -r1.15 src/sys/kern/subr_pcu.c
cvs rdiff -u -r1.10 -r1.11 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/alpha/include/alpha.h
diff -u src/sys/arch/alpha/include/alpha.h:1.31 src/sys/arch/alpha/include/alpha.h:1.32
--- src/sys/arch/alpha/include/alpha.h:1.31	Wed Dec 26 19:13:19 2012
+++ src/sys/arch/alpha/include/alpha.h	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha.h,v 1.31 2012/12/26 19:13:19 matt Exp $ */
+/* $NetBSD: alpha.h,v 1.32 2013/08/22 19:50:54 drochner Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -128,7 +128,7 @@ fpu_save(void)
 static inline void
 fpu_discard(void)
 {
-	pcu_discard(&fpu_ops);
+	pcu_discard(&fpu_ops, false);
 }
 
 void	alpha_patch(bool);

Index: src/sys/arch/arm/vfp/vfp_init.c
diff -u src/sys/arch/arm/vfp/vfp_init.c:1.23 src/sys/arch/arm/vfp/vfp_init.c:1.24
--- src/sys/arch/arm/vfp/vfp_init.c:1.23	Sun Aug 18 06:28:18 2013
+++ src/sys/arch/arm/vfp/vfp_init.c	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*      $NetBSD: vfp_init.c,v 1.23 2013/08/18 06:28:18 matt Exp $ */
+/*      $NetBSD: vfp_init.c,v 1.24 2013/08/22 19:50:54 drochner Exp $ */
 
 /*
  * Copyright (c) 2008 ARM Ltd
@@ -601,7 +601,7 @@ vfp_savecontext(void)
 void
 vfp_discardcontext(void)
 {
-	pcu_discard(&arm_vfp_ops);
+	pcu_discard(&arm_vfp_ops, false);
 }
 
 void
@@ -656,7 +656,7 @@ vfp_getcontext(struct lwp *l, mcontext_t
 void
 vfp_setcontext(struct lwp *l, const mcontext_t *mcp)
 {
-	pcu_discard(&arm_vfp_ops);
+	pcu_discard(&arm_vfp_ops, true);
 	struct pcb * const pcb = lwp_getpcb(l);
 	l->l_md.md_flags |= MDLWP_VFPUSED;
 	pcb->pcb_vfp.vfp_fpscr = mcp->__fpu.__vfpregs.__vfp_fpscr;

Index: src/sys/arch/mips/mips/mips_dsp.c
diff -u src/sys/arch/mips/mips/mips_dsp.c:1.2 src/sys/arch/mips/mips/mips_dsp.c:1.3
--- src/sys/arch/mips/mips/mips_dsp.c:1.2	Wed Dec 26 19:17:48 2012
+++ src/sys/arch/mips/mips/mips_dsp.c	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_dsp.c,v 1.2 2012/12/26 19:17:48 matt Exp $	*/
+/*	$NetBSD: mips_dsp.c,v 1.3 2013/08/22 19:50:54 drochner Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_dsp.c,v 1.2 2012/12/26 19:17:48 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_dsp.c,v 1.3 2013/08/22 19:50:54 drochner Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -60,7 +60,7 @@ const pcu_ops_t mips_dsp_ops = {
 void
 dsp_discard(void)
 {
-	pcu_discard(&mips_dsp_ops);
+	pcu_discard(&mips_dsp_ops, false);
 }
 
 void

Index: src/sys/arch/mips/mips/mips_fpu.c
diff -u src/sys/arch/mips/mips/mips_fpu.c:1.10 src/sys/arch/mips/mips/mips_fpu.c:1.11
--- src/sys/arch/mips/mips/mips_fpu.c:1.10	Wed Dec 26 19:15:16 2012
+++ src/sys/arch/mips/mips/mips_fpu.c	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_fpu.c,v 1.10 2012/12/26 19:15:16 matt Exp $	*/
+/*	$NetBSD: mips_fpu.c,v 1.11 2013/08/22 19:50:54 drochner 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.10 2012/12/26 19:15:16 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_fpu.c,v 1.11 2013/08/22 19:50:54 drochner Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -60,7 +60,7 @@ const pcu_ops_t mips_fpu_ops = {
 void
 fpu_discard(void)
 {
-	pcu_discard(&mips_fpu_ops);
+	pcu_discard(&mips_fpu_ops, false);
 }
 
 void

Index: src/sys/arch/powerpc/include/altivec.h
diff -u src/sys/arch/powerpc/include/altivec.h:1.15 src/sys/arch/powerpc/include/altivec.h:1.16
--- src/sys/arch/powerpc/include/altivec.h:1.15	Mon May  2 06:29:23 2011
+++ src/sys/arch/powerpc/include/altivec.h	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.h,v 1.15 2011/05/02 06:29:23 matt Exp $	*/
+/*	$NetBSD: altivec.h,v 1.16 2013/08/22 19:50:54 drochner Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@ vec_save(void)
 static inline void
 vec_discard(void)
 {
-	pcu_discard(&vec_ops);
+	pcu_discard(&vec_ops, false);
 }
 
 void	vec_load_from_vreg(const struct vreg *);

Index: src/sys/arch/powerpc/include/fpu.h
diff -u src/sys/arch/powerpc/include/fpu.h:1.19 src/sys/arch/powerpc/include/fpu.h:1.20
--- src/sys/arch/powerpc/include/fpu.h:1.19	Thu May 19 08:22:38 2011
+++ src/sys/arch/powerpc/include/fpu.h	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.h,v 1.19 2011/05/19 08:22:38 kiyohara Exp $	*/
+/*	$NetBSD: fpu.h,v 1.20 2013/08/22 19:50:54 drochner Exp $	*/
 
 /*-
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -106,7 +106,7 @@ fpu_save(void)
 static inline void
 fpu_discard(void)
 {
-	pcu_discard(&fpu_ops);
+	pcu_discard(&fpu_ops, false);
 }
 
 void	fpu_load_from_fpreg(const struct fpreg *);

Index: src/sys/arch/powerpc/oea/altivec.c
diff -u src/sys/arch/powerpc/oea/altivec.c:1.26 src/sys/arch/powerpc/oea/altivec.c:1.27
--- src/sys/arch/powerpc/oea/altivec.c:1.26	Wed Dec 26 19:05:03 2012
+++ src/sys/arch/powerpc/oea/altivec.c	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.c,v 1.26 2012/12/26 19:05:03 matt Exp $	*/
+/*	$NetBSD: altivec.c,v 1.27 2013/08/22 19:50:54 drochner Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.26 2012/12/26 19:05:03 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.27 2013/08/22 19:50:54 drochner Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -164,7 +164,7 @@ vec_restore_from_mcontext(struct lwp *l,
 	KASSERT(l == curlwp);
 
 	/* we don't need to save the state, just drop it */
-	pcu_discard(&vec_ops);
+	pcu_discard(&vec_ops, true);
 	memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg));
 	pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
 	pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;

Index: src/sys/arch/powerpc/powerpc/fpu.c
diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.32 src/sys/arch/powerpc/powerpc/fpu.c:1.33
--- src/sys/arch/powerpc/powerpc/fpu.c:1.32	Wed Dec 26 19:05:03 2012
+++ src/sys/arch/powerpc/powerpc/fpu.c	Thu Aug 22 19:50:54 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.c,v 1.32 2012/12/26 19:05:03 matt Exp $	*/
+/*	$NetBSD: fpu.c,v 1.33 2013/08/22 19:50:54 drochner Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.32 2012/12/26 19:05:03 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.33 2013/08/22 19:50:54 drochner Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -242,7 +242,7 @@ fpu_restore_from_mcontext(lwp_t *l, cons
 #ifdef PPC_HAVE_FPU
 	/* we don't need to save the state, just drop it */
 	if (l == curlwp)
-		pcu_discard(&fpu_ops);
+		pcu_discard(&fpu_ops, true);
 #endif
 	(void)memcpy(&pcb->pcb_fpu.fpreg, &mcp->__fpregs.__fpu_regs,
 	    sizeof (pcb->pcb_fpu.fpreg));

Index: src/sys/kern/kern_cpu.c
diff -u src/sys/kern/kern_cpu.c:1.59 src/sys/kern/kern_cpu.c:1.60
--- src/sys/kern/kern_cpu.c:1.59	Wed Oct 17 20:19:55 2012
+++ src/sys/kern/kern_cpu.c	Thu Aug 22 19:50:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_cpu.c,v 1.59 2012/10/17 20:19:55 drochner Exp $	*/
+/*	$NetBSD: kern_cpu.c,v 1.60 2013/08/22 19:50:55 drochner Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009, 2010, 2012 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.59 2012/10/17 20:19:55 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.60 2013/08/22 19:50:55 drochner Exp $");
 
 #include "opt_cpu_ucode.h"
 #include "opt_compat_netbsd.h"
@@ -79,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v
 #include <sys/select.h>
 #include <sys/namei.h>
 #include <sys/callout.h>
+#include <sys/pcu.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -389,6 +390,10 @@ cpu_xc_offline(struct cpu_info *ci)
 	}
 	mutex_exit(proc_lock);
 
+#if PCU_UNIT_COUNT > 0
+	pcu_save_all_on_cpu();
+#endif
+
 #ifdef __HAVE_MD_CPU_OFFLINE
 	cpu_offline_md();
 #endif

Index: src/sys/kern/subr_pcu.c
diff -u src/sys/kern/subr_pcu.c:1.14 src/sys/kern/subr_pcu.c:1.15
--- src/sys/kern/subr_pcu.c:1.14	Mon Dec 31 01:20:05 2012
+++ src/sys/kern/subr_pcu.c	Thu Aug 22 19:50:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_pcu.c,v 1.14 2012/12/31 01:20:05 matt Exp $	*/
+/*	$NetBSD: subr_pcu.c,v 1.15 2013/08/22 19:50:55 drochner 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.14 2012/12/31 01:20:05 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.15 2013/08/22 19:50:55 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -385,20 +385,25 @@ pcu_load(const pcu_ops_t *pcu)
 
 /*
  * pcu_discard: discard the PCU state of current LWP.
+ * If the "usesw" flag is set, pcu_used_p() will return "true".
  */
 void
-pcu_discard(const pcu_ops_t *pcu)
+pcu_discard(const pcu_ops_t *pcu, bool usesw)
 {
 	const u_int id = pcu->pcu_id;
 	lwp_t * const l = curlwp;
 
 	KASSERT(!cpu_intr_p() && !cpu_softintr_p());
 
+	if (usesw)
+		l->l_pcu_used[PCU_USER] |= (1 << id);
+	else
+		l->l_pcu_used[PCU_USER] &= ~(1 << id);
+
 	if (__predict_true(l->l_pcu_cpu[id] == NULL)) {
 		return;
 	}
 	pcu_lwp_op(pcu, l, PCU_RELEASE);
-	l->l_pcu_used[PCU_USER] &= ~(1 << id);
 }
 
 /*
@@ -419,6 +424,18 @@ pcu_save(const pcu_ops_t *pcu)
 }
 
 /*
+ * pcu_save_all_on_cpu: save all PCU state on current CPU
+ */
+void
+pcu_save_all_on_cpu(void)
+{
+
+	for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
+		pcu_cpu_op(pcu_ops_md_defs[id], PCU_SAVE | PCU_RELEASE);
+	}
+}
+
+/*
  * pcu_used: return true if PCU was used (pcu_load() case) by the LWP.
  */
 bool
@@ -427,7 +444,7 @@ 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[0] & (1 << id);
+	return l->l_pcu_used[PCU_USER] & (1 << id);
 }
 
 void

Index: src/sys/sys/pcu.h
diff -u src/sys/sys/pcu.h:1.10 src/sys/sys/pcu.h:1.11
--- src/sys/sys/pcu.h:1.10	Wed Dec 26 18:30:22 2012
+++ src/sys/sys/pcu.h	Thu Aug 22 19:50:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcu.h,v 1.10 2012/12/26 18:30:22 matt Exp $	*/
+/*	$NetBSD: pcu.h,v 1.11 2013/08/22 19:50:55 drochner Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -82,7 +82,8 @@ void	pcu_save_all(lwp_t *);
 
 void	pcu_load(const pcu_ops_t *);
 void	pcu_save(const pcu_ops_t *);
-void	pcu_discard(const pcu_ops_t *);
+void	pcu_save_all_on_cpu(void);
+void	pcu_discard(const pcu_ops_t *, bool);
 void	pcu_kernel_acquire(const pcu_ops_t *);
 void	pcu_kernel_release(const pcu_ops_t *);
 bool	pcu_used_p(const pcu_ops_t *);

Reply via email to