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