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