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