diff options
| author | ad <ad@NetBSD.org> | 2007-12-26 16:01:34 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2007-12-26 16:01:34 +0000 |
| commit | ea3f10f7e0bbec1b91020f8a5f122d418ab2fbcc (patch) | |
| tree | 76b2e7de3e201fd39b888fe4985745e3d166aad8 | |
| parent | 890b62431b0627bd148b755191009d3d0b9ca813 (diff) | |
Merge more changes from vmlocking2, mainly:
- Locking improvements.
- Use pool_cache for more items.
| -rw-r--r-- | sys/arch/mips/include/pmap.h | 4 | ||||
| -rw-r--r-- | sys/arch/mips/include/vmparam.h | 6 | ||||
| -rw-r--r-- | sys/arch/mips/mips/pmap.c | 12 | ||||
| -rw-r--r-- | sys/compat/svr4/svr4_misc.c | 5 | ||||
| -rw-r--r-- | sys/conf/param.c | 6 | ||||
| -rw-r--r-- | sys/kern/init_main.c | 7 | ||||
| -rw-r--r-- | sys/kern/kern_descrip.c | 102 | ||||
| -rw-r--r-- | sys/kern/kern_exec.c | 46 | ||||
| -rw-r--r-- | sys/kern/kern_exit.c | 7 | ||||
| -rw-r--r-- | sys/kern/kern_lwp.c | 13 | ||||
| -rw-r--r-- | sys/kern/kern_proc.c | 89 | ||||
| -rw-r--r-- | sys/kern/kern_resource.c | 25 | ||||
| -rw-r--r-- | sys/kern/subr_lockdebug.c | 7 | ||||
| -rw-r--r-- | sys/kern/subr_pool.c | 86 | ||||
| -rw-r--r-- | sys/kern/sys_pipe.c | 290 | ||||
| -rw-r--r-- | sys/kern/tty.c | 49 | ||||
| -rw-r--r-- | sys/kern/uipc_syscalls.c | 8 | ||||
| -rw-r--r-- | sys/kern/vfs_syscalls.c | 26 | ||||
| -rw-r--r-- | sys/miscfs/procfs/procfs_vfsops.c | 5 | ||||
| -rw-r--r-- | sys/sys/file.h | 6 | ||||
| -rw-r--r-- | sys/sys/lwp.h | 4 | ||||
| -rw-r--r-- | sys/sys/pipe.h | 4 | ||||
| -rw-r--r-- | sys/sys/pool.h | 6 | ||||
| -rw-r--r-- | sys/sys/proc.h | 8 | ||||
| -rw-r--r-- | sys/sys/resourcevar.h | 3 | ||||
| -rw-r--r-- | usr.bin/sockstat/sockstat.c | 6 | ||||
| -rw-r--r-- | usr.bin/vmstat/vmstat.c | 16 |
27 files changed, 445 insertions, 401 deletions
diff --git a/sys/arch/mips/include/pmap.h b/sys/arch/mips/include/pmap.h index 27f7d7dfb7d..7fa2027684b 100644 --- a/sys/arch/mips/include/pmap.h +++ b/sys/arch/mips/include/pmap.h @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.53 2007/10/17 19:55:37 garbled Exp $ */ +/* $NetBSD: pmap.h,v 1.54 2007/12/26 16:01:34 ad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -115,7 +115,7 @@ struct segtab { */ typedef struct pmap { int pm_count; /* pmap reference count */ - struct simplelock pm_lock; /* lock on pmap */ + kmutex_t pm_lock; /* lock on pmap */ struct pmap_statistics pm_stats; /* pmap statistics */ unsigned pm_asid; /* TLB address space tag */ unsigned pm_asidgen; /* its generation number */ diff --git a/sys/arch/mips/include/vmparam.h b/sys/arch/mips/include/vmparam.h index eeb274e0d17..0a79354ad3e 100644 --- a/sys/arch/mips/include/vmparam.h +++ b/sys/arch/mips/include/vmparam.h @@ -1,4 +1,4 @@ -/* $NetBSD: vmparam.h,v 1.40 2007/12/03 15:33:55 ad Exp $ */ +/* $NetBSD: vmparam.h,v 1.41 2007/12/26 16:01:34 ad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -79,8 +79,6 @@ #ifndef _MIPS_VMPARAM_H_ #define _MIPS_VMPARAM_H_ -#include <sys/simplelock.h> - /* * Machine dependent VM constants for MIPS. */ @@ -176,14 +174,12 @@ */ struct vm_page_md { struct pv_entry *pvh_list; /* pv_entry list */ - struct simplelock pvh_slock; /* lock on this head */ u_int pvh_attrs; /* page attributes */ }; #define VM_MDPAGE_INIT(pg) \ do { \ (pg)->mdpage.pvh_list = NULL; \ - simple_lock_init(&(pg)->mdpage.pvh_slock); \ } while (/* CONSTCOND */ 0) #endif /* ! _MIPS_VMPARAM_H_ */ diff --git a/sys/arch/mips/mips/pmap.c b/sys/arch/mips/mips/pmap.c index 4d3ac24210c..7f2d347ffdb 100644 --- a/sys/arch/mips/mips/pmap.c +++ b/sys/arch/mips/mips/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.177 2007/10/25 13:03:04 yamt Exp $ */ +/* $NetBSD: pmap.c,v 1.178 2007/12/26 16:01:34 ad Exp $ */ /*- * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.177 2007/10/25 13:03:04 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.178 2007/12/26 16:01:34 ad Exp $"); /* * Manages physical address maps. @@ -129,6 +129,7 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.177 2007/10/25 13:03:04 yamt Exp $"); #include <sys/user.h> #include <sys/buf.h> #include <sys/pool.h> +#include <sys/mutex.h> #ifdef SYSVSHM #include <sys/shm.h> #endif @@ -364,7 +365,6 @@ pmap_bootstrap(void) /* * Initialize the kernel pmap. */ - simple_lock_init(&pmap_kernel()->pm_lock); pmap_kernel()->pm_count = 1; pmap_kernel()->pm_asid = PMAP_ASID_RESERVED; pmap_kernel()->pm_asidgen = 0; @@ -568,7 +568,6 @@ pmap_create(void) pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); memset(pmap, 0, sizeof(*pmap)); - simple_lock_init(&pmap->pm_lock); pmap->pm_count = 1; if (free_segtab) { pmap->pm_segtab = free_segtab; @@ -624,10 +623,7 @@ pmap_destroy(pmap_t pmap) if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) printf("pmap_destroy(%p)\n", pmap); #endif - simple_lock(&pmap->pm_lock); count = --pmap->pm_count; - simple_unlock(&pmap->pm_lock); - if (count > 0) return; @@ -686,9 +682,7 @@ pmap_reference(pmap_t pmap) printf("pmap_reference(%p)\n", pmap); #endif if (pmap != NULL) { - simple_lock(&pmap->pm_lock); pmap->pm_count++; - simple_unlock(&pmap->pm_lock); } } diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 58d384fa7b4..59dbf0d5f42 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_misc.c,v 1.136 2007/12/20 23:03:05 dsl Exp $ */ +/* $NetBSD: svr4_misc.c,v 1.137 2007/12/26 16:01:35 ad Exp $ */ /*- * Copyright (c) 1994 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.136 2007/12/20 23:03:05 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.137 2007/12/26 16:01:35 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -567,7 +567,6 @@ svr4_sys_vhangup(struct lwp *l, const void *v, register_t *retval) int svr4_sys_sysconfig(struct lwp *l, const struct svr4_sys_sysconfig_args *uap, register_t *retval) { - extern int maxfiles; int active; switch (SCARG(uap, name)) { diff --git a/sys/conf/param.c b/sys/conf/param.c index 0afd3e4c76b..5327edcac82 100644 --- a/sys/conf/param.c +++ b/sys/conf/param.c @@ -1,4 +1,4 @@ -/* $NetBSD: param.c,v 1.52 2007/05/17 14:51:37 yamt Exp $ */ +/* $NetBSD: param.c,v 1.53 2007/12/26 16:01:35 ad Exp $ */ /* * Copyright (c) 1980, 1986, 1989 Regents of the University of California. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: param.c,v 1.52 2007/05/17 14:51:37 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: param.c,v 1.53 2007/12/26 16:01:35 ad Exp $"); #include "opt_hz.h" #include "opt_rtc_offset.h" @@ -108,7 +108,7 @@ int tickadj = (240000 / (60 * HZ)) ? (240000 / (60 * HZ)) : 1; int rtc_offset = RTC_OFFSET; int maxproc = NPROC; int desiredvnodes = NVNODE; -int maxfiles = MAXFILES; +u_int maxfiles = MAXFILES; int fscale = FSCALE; /* kernel uses `FSCALE', user uses `fscale' */ /* diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 8db5a3a93f4..0b677fa9a0e 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.332 2007/12/22 01:14:53 yamt Exp $ */ +/* $NetBSD: init_main.c,v 1.333 2007/12/26 16:01:35 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.332 2007/12/22 01:14:53 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.333 2007/12/26 16:01:35 ad Exp $"); #include "opt_ipsec.h" #include "opt_ntp.h" @@ -335,6 +335,9 @@ main(void) /* Initialize signal-related data structures. */ signal_init(); + /* Initialize resource management. */ + resource_init(); + /* Create process 0 (the swapper). */ proc0_init(); diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a260fa4c79f..ad1958d6f8b 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_descrip.c,v 1.166 2007/12/20 23:03:07 dsl Exp $ */ +/* $NetBSD: kern_descrip.c,v 1.167 2007/12/26 16:01:35 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.166 2007/12/20 23:03:07 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.167 2007/12/26 16:01:35 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -67,12 +67,14 @@ __KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.166 2007/12/20 23:03:07 dsl Exp $ static int cwdi_ctor(void *, void *, int); static void cwdi_dtor(void *, void *); +static int file_ctor(void *, void *, int); +static void file_dtor(void *, void *); /* * Descriptor management. */ struct filelist filehead; /* head of list of open files */ -int nfiles; /* actual number of open files */ +u_int nfiles; /* actual number of open files */ static pool_cache_t cwdi_cache; static pool_cache_t filedesc0_cache; @@ -270,7 +272,7 @@ filedesc_init(void) mutex_init(&filelist_lock, MUTEX_DEFAULT, IPL_NONE); file_cache = pool_cache_init(sizeof(struct file), 0, 0, 0, - "filepl", NULL, IPL_NONE, NULL, NULL, NULL); + "filepl", NULL, IPL_NONE, file_ctor, file_dtor, NULL); KASSERT(file_cache != NULL); cwdi_cache = pool_cache_init(sizeof(struct cwdinfo), 0, 0, 0, @@ -1009,7 +1011,7 @@ int falloc(struct lwp *l, struct file **resultfp, int *resultfd) { struct filedesc *fdp; - struct file *fp, *fq; + struct file *fp; struct proc *p; int error, i; @@ -1026,45 +1028,44 @@ falloc(struct lwp *l, struct file **resultfp, int *resultfd) } fp = pool_cache_get(file_cache, PR_WAITOK); - memset(fp, 0, sizeof(struct file)); - mutex_init(&fp->f_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_enter(&filelist_lock); - if (nfiles >= maxfiles) { + + if (atomic_inc_uint_nv(&nfiles) >= maxfiles) { + atomic_dec_uint(&nfiles); tablefull("file", "increase kern.maxfiles or MAXFILES"); - mutex_exit(&filelist_lock); rw_enter(&fdp->fd_lock, RW_WRITER); fd_unused(fdp, i); rw_exit(&fdp->fd_lock); - mutex_destroy(&fp->f_lock); pool_cache_put(file_cache, fp); return (ENFILE); } + + fp->f_advice = 0; + fp->f_msgcount = 0; + fp->f_offset = 0; + /* * Allocate a new file descriptor. * If the process has file descriptor zero open, add to the list * of open files at that point, otherwise put it at the front of * the list of open files. */ - nfiles++; fp->f_iflags = FIF_LARVAL; - cv_init(&fp->f_cv, "closef"); + fp->f_cred = l->l_cred; + kauth_cred_hold(fp->f_cred); + + mutex_enter(&fp->f_lock); + fp->f_count = 1; + mutex_exit(&fp->f_lock); + rw_enter(&fdp->fd_lock, RW_WRITER); /* XXXAD check order */ - if ((fq = fdp->fd_ofiles[0]) != NULL) { - LIST_INSERT_AFTER(fq, fp, f_list); - } else { - LIST_INSERT_HEAD(&filehead, fp, f_list); - } KDASSERT(fdp->fd_ofiles[i] == NULL); fdp->fd_ofiles[i] = fp; - fp->f_count = 1; - fp->f_cred = l->l_cred; - kauth_cred_hold(fp->f_cred); + rw_exit(&fdp->fd_lock); + if (resultfp) { fp->f_usecount = 1; *resultfp = fp; } - mutex_exit(&filelist_lock); - rw_exit(&fdp->fd_lock); if (resultfd) *resultfd = i; @@ -1077,26 +1078,12 @@ falloc(struct lwp *l, struct file **resultfp, int *resultfd) void ffree(struct file *fp) { - kauth_cred_t cred; -#ifdef DIAGNOSTIC - if (fp->f_usecount) - panic("ffree"); -#endif + KASSERT(fp->f_usecount == 0); - mutex_enter(&filelist_lock); - LIST_REMOVE(fp, f_list); - cred = fp->f_cred; -#ifdef DIAGNOSTIC - fp->f_cred = NULL; - fp->f_count = 0; /* What's the point? */ -#endif - nfiles--; - mutex_exit(&filelist_lock); - mutex_destroy(&fp->f_lock); - cv_destroy(&fp->f_cv); + atomic_dec_uint(&nfiles); + kauth_cred_free(fp->f_cred); pool_cache_put(file_cache, fp); - kauth_cred_free(cred); } /* @@ -1132,9 +1119,8 @@ cwdinit(struct proc *p) static int cwdi_ctor(void *arg, void *obj, int flags) { - struct cwdinfo *cwdi; + struct cwdinfo *cwdi = obj; - cwdi = obj; rw_init(&cwdi->cwdi_lock); return 0; @@ -1143,12 +1129,40 @@ cwdi_ctor(void *arg, void *obj, int flags) static void cwdi_dtor(void *arg, void *obj) { - struct cwdinfo *cwdi; + struct cwdinfo *cwdi = obj; - cwdi = obj; rw_destroy(&cwdi->cwdi_lock); } +static int +file_ctor(void *arg, void *obj, int flags) +{ + struct file *fp = obj; + + memset(fp, 0, sizeof(*fp)); + mutex_init(&fp->f_lock, MUTEX_DEFAULT, IPL_NONE); + cv_init(&fp->f_cv, "closef"); + + mutex_enter(&filelist_lock); + LIST_INSERT_HEAD(&filehead, fp, f_list); + mutex_exit(&filelist_lock); + + return 0; +} + +static void +file_dtor(void *arg, void *obj) +{ + struct file *fp = obj; + + mutex_enter(&filelist_lock); + LIST_REMOVE(fp, f_list); + mutex_exit(&filelist_lock); + + mutex_destroy(&fp->f_lock); + cv_destroy(&fp->f_cv); +} + /* * Make p2 share p1's cwdinfo. */ diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 39a0181fed2..190fb71e5b4 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.258 2007/12/20 23:03:08 dsl Exp $ */ +/* $NetBSD: kern_exec.c,v 1.259 2007/12/26 16:01:35 ad Exp $ */ /*- * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.258 2007/12/20 23:03:08 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.259 2007/12/26 16:01:35 ad Exp $"); #include "opt_ktrace.h" #include "opt_syscall_debug.h" @@ -207,6 +207,8 @@ krwlock_t exec_lock; static void link_es(struct execsw_entry **, const struct execsw *); #endif /* LKM */ +static kmutex_t sigobject_lock; + /* * check exec: * given an "executable" described in the exec package's namei info, @@ -811,7 +813,9 @@ execve1(struct lwp *l, const char *path, char * const *args, p->p_acflag &= ~AFORK; + mutex_enter(&p->p_mutex); p->p_flag |= PK_EXEC; + mutex_exit(&p->p_mutex); /* * Stop profiling. @@ -948,7 +952,9 @@ execve1(struct lwp *l, const char *path, char * const *args, emul_find_root(l, &pack); /* Any old emulation root got removed by fdcloseexec */ + rw_enter(&p->p_cwdi->cwdi_lock, RW_WRITER); p->p_cwdi->cwdi_edir = pack.ep_emul_root; + rw_exit(&p->p_cwdi->cwdi_lock); pack.ep_emul_root = NULL; if (pack.ep_interp != NULL) vrele(pack.ep_interp); @@ -1389,6 +1395,7 @@ exec_init(int init_boot) if (init_boot) { /* do one-time initializations */ rw_init(&exec_lock); + mutex_init(&sigobject_lock, MUTEX_DEFAULT, IPL_NONE); /* register compiled-in emulations */ for(i=0; i < nexecs_builtin; i++) { @@ -1514,23 +1521,28 @@ exec_sigcode_map(struct proc *p, const struct emul *e) uobj = *e->e_sigobject; if (uobj == NULL) { - uobj = uao_create(sz, 0); - (*uobj->pgops->pgo_reference)(uobj); - va = vm_map_min(kernel_map); - if ((error = uvm_map(kernel_map, &va, round_page(sz), - uobj, 0, 0, - UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, - UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) { - printf("kernel mapping failed %d\n", error); - (*uobj->pgops->pgo_detach)(uobj); - return (error); - } - memcpy((void *)va, e->e_sigcode, sz); + mutex_enter(&sigobject_lock); + if ((uobj = *e->e_sigobject) == NULL) { + uobj = uao_create(sz, 0); + (*uobj->pgops->pgo_reference)(uobj); + va = vm_map_min(kernel_map); + if ((error = uvm_map(kernel_map, &va, round_page(sz), + uobj, 0, 0, + UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, + UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) { + printf("kernel mapping failed %d\n", error); + (*uobj->pgops->pgo_detach)(uobj); + mutex_exit(&sigobject_lock); + return (error); + } + memcpy((void *)va, e->e_sigcode, sz); #ifdef PMAP_NEED_PROCWR - pmap_procwr(&proc0, va, sz); + pmap_procwr(&proc0, va, sz); #endif - uvm_unmap(kernel_map, va, va + round_page(sz)); - *e->e_sigobject = uobj; + uvm_unmap(kernel_map, va, va + round_page(sz)); + *e->e_sigobject = uobj; + } + mutex_exit(&sigobject_lock); } /* Just a hint to uvm_map where to put it. */ diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 4458aa0e7d4..056942c3446 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exit.c,v 1.195 2007/12/20 23:03:08 dsl Exp $ */ +/* $NetBSD: kern_exit.c,v 1.196 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 1998, 1999, 2006, 2007 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.195 2007/12/20 23:03:08 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.196 2007/12/26 16:01:36 ad Exp $"); #include "opt_ktrace.h" #include "opt_perfctrs.h" @@ -427,6 +427,7 @@ exit1(struct lwp *l, int rv) */ KNOTE(&p->p_klist, NOTE_EXIT); + #if PERFCTRS /* * Save final PMC information in parent process & clean up. @@ -1002,7 +1003,7 @@ proc_free(struct proc *p, struct rusage *ru) cv_destroy(&p->p_lwpcv); rw_destroy(&p->p_reflock); - pool_put(&proc_pool, p); + proc_free_mem(p); /* * Collect child u-areas. diff --git a/sys/kern/kern_lwp.c b/sys/kern/kern_lwp.c index 4972f8cadb4..9802c5bc427 100644 --- a/sys/kern/kern_lwp.c +++ b/sys/kern/kern_lwp.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.86 2007/12/22 01:14:54 yamt Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.87 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc. @@ -205,7 +205,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.86 2007/12/22 01:14:54 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.87 2007/12/26 16:01:36 ad Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -234,11 +234,10 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.86 2007/12/22 01:14:54 yamt Exp $"); struct lwplist alllwp = LIST_HEAD_INITIALIZER(alllwp); -POOL_INIT(lwp_pool, sizeof(struct lwp), MIN_LWP_ALIGNMENT, 0, 0, "lwppl", - &pool_allocator_nointr, IPL_NONE); POOL_INIT(lwp_uc_pool, sizeof(ucontext_t), 0, 0, 0, "lwpucpl", &pool_allocator_nointr, IPL_NONE); +static pool_cache_t lwp_cache; static specificdata_domain_t lwp_specificdata_domain; void @@ -248,6 +247,8 @@ lwpinit(void) lwp_specificdata_domain = specificdata_domain_create(); KASSERT(lwp_specificdata_domain != NULL); lwp_sys_init(); + lwp_cache = pool_cache_init(sizeof(lwp_t), MIN_LWP_ALIGNMENT, 0, 0, + "lwppl", NULL, IPL_NONE, NULL, NULL, NULL); } /* @@ -556,7 +557,7 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, bool inmem, int flags, mutex_exit(&p2->p_smutex); } if (isfree == NULL) { - l2 = pool_get(&lwp_pool, PR_WAITOK); + l2 = pool_cache_get(lwp_cache, PR_WAITOK); memset(l2, 0, sizeof(*l2)); l2->l_ts = pool_cache_get(turnstile_cache, PR_WAITOK); SLIST_INIT(&l2->l_pi_lenders); @@ -927,7 +928,7 @@ lwp_free(struct lwp *l, bool recycle, bool last) KASSERT(SLIST_EMPTY(&l->l_pi_lenders)); KASSERT(l->l_inheritedprio == -1); if (!recycle) - pool_put(&lwp_pool, l); + pool_cache_put(lwp_cache, l); KERNEL_UNLOCK_ONE(curlwp); /* XXXSMP */ } diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index fb034e80f4b..f6767c89878 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_proc.c,v 1.127 2007/12/05 07:06:53 ad Exp $ */ +/* $NetBSD: kern_proc.c,v 1.128 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 1999, 2006, 2007 The NetBSD Foundation, Inc. @@ -69,7 +69,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.127 2007/12/05 07:06:53 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.128 2007/12/26 16:01:36 ad Exp $"); #include "opt_kstack.h" #include "opt_maxuprc.h" @@ -273,17 +273,6 @@ int nofile = NOFILE; int maxuprc = MAXUPRC; int cmask = CMASK; -POOL_INIT(proc_pool, sizeof(struct proc), 0, 0, 0, "procpl", - &pool_allocator_nointr, IPL_NONE); -POOL_INIT(pgrp_pool, sizeof(struct pgrp), 0, 0, 0, "pgrppl", - &pool_allocator_nointr, IPL_NONE); -POOL_INIT(plimit_pool, sizeof(struct plimit), 0, 0, 0, "plimitpl", - &pool_allocator_nointr, IPL_NONE); -POOL_INIT(pstats_pool, sizeof(struct pstats), 0, 0, 0, "pstatspl", - &pool_allocator_nointr, IPL_NONE); -POOL_INIT(session_pool, sizeof(struct session), 0, 0, 0, "sessionpl", - &pool_allocator_nointr, IPL_NONE); - MALLOC_DEFINE(M_EMULDATA, "emuldata", "Per-process emulation data"); MALLOC_DEFINE(M_PROC, "proc", "Proc structures"); MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); @@ -304,6 +293,10 @@ static void pg_delete(pid_t); static specificdata_domain_t proc_specificdata_domain; +static pool_cache_t proc_cache; +static pool_cache_t pgrp_cache; +static pool_cache_t session_cache; + /* * Initialize global process hashing structures. */ @@ -342,6 +335,13 @@ procinit(void) proc_specificdata_domain = specificdata_domain_create(); KASSERT(proc_specificdata_domain != NULL); + + proc_cache = pool_cache_init(sizeof(struct proc), 0, 0, 0, + "procpl", NULL, IPL_NONE, NULL, NULL, NULL); + pgrp_cache = pool_cache_init(sizeof(struct pgrp), 0, 0, 0, + "pgrppl", NULL, IPL_NONE, NULL, NULL, NULL); + session_cache = pool_cache_init(sizeof(struct session), 0, 0, 0, + "sessionpl", NULL, IPL_NONE, NULL, NULL, NULL); } /* @@ -633,7 +633,7 @@ proc_alloc(void) pid_t pid; struct pid_table *pt; - p = pool_get(&proc_pool, PR_WAITOK); + p = pool_cache_get(proc_cache, PR_WAITOK); p->p_stat = SIDL; /* protect against others */ proc_initspecific(p); @@ -710,6 +710,13 @@ proc_free_pid(struct proc *p) atomic_dec_uint(&nprocs); } +void +proc_free_mem(struct proc *p) +{ + + pool_cache_put(proc_cache, p); +} + /* * Move p to a new or existing process group (and session) * @@ -732,7 +739,7 @@ enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, int mksess) pid_t pg_id = NO_PGID; if (mksess) - sess = pool_get(&session_pool, PR_WAITOK); + sess = pool_cache_get(session_cache, PR_WAITOK); else sess = NULL; @@ -740,7 +747,7 @@ enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, int mksess) mutex_enter(&proclist_lock); /* Because pid_table might change */ if (pid_table[pgid & pid_tbl_mask].pt_pgrp == 0) { mutex_exit(&proclist_lock); - new_pgrp = pool_get(&pgrp_pool, PR_WAITOK); + new_pgrp = pool_cache_get(pgrp_cache, PR_WAITOK); mutex_enter(&proclist_lock); } else new_pgrp = NULL; @@ -846,17 +853,8 @@ enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, int mksess) } else mutex_enter(&proclist_mutex); -#ifdef notyet - /* - * If there's a controlling terminal for the current session, we - * have to interlock with it. See ttread(). - */ - if (p->p_session->s_ttyvp != NULL) { - tp = p->p_session->s_ttyp; - mutex_enter(&tp->t_mutex); - } else - tp = NULL; -#endif + /* Interlock with tty subsystem. */ + mutex_spin_enter(&tty_lock); /* * Adjust eligibility of affected pgrps to participate in job control. @@ -873,22 +871,20 @@ enterpgrp(struct proc *curp, pid_t pid, pid_t pgid, int mksess) pg_id = p->p_pgrp->pg_id; p->p_pgrp = pgrp; LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); - mutex_exit(&proclist_mutex); -#ifdef notyet /* Done with the swap; we can release the tty mutex. */ - if (tp != NULL) - mutex_exit(&tp->t_mutex); -#endif + mutex_spin_exit(&tty_lock); + + mutex_exit(&proclist_mutex); done: if (pg_id != NO_PGID) pg_delete(pg_id); mutex_exit(&proclist_lock); if (sess != NULL) - pool_put(&session_pool, sess); + pool_cache_put(session_cache, sess); if (new_pgrp != NULL) - pool_put(&pgrp_pool, new_pgrp); + pool_cache_put(pgrp_cache, new_pgrp); #ifdef DEBUG_PGRP if (__predict_false(rval)) printf("enterpgrp(%d,%d,%d), curproc %d, rval %d\n", @@ -908,27 +904,12 @@ leavepgrp(struct proc *p) KASSERT(mutex_owned(&proclist_lock)); - /* - * If there's a controlling terminal for the session, we have to - * interlock with it. See ttread(). - */ mutex_enter(&proclist_mutex); -#ifdef notyet - if (p_>p_session->s_ttyvp != NULL) { - tp = p->p_session->s_ttyp; - mutex_enter(&tp->t_mutex); - } else - tp = NULL; -#endif - + mutex_spin_enter(&tty_lock); pgrp = p->p_pgrp; LIST_REMOVE(p, p_pglist); p->p_pgrp = NULL; - -#ifdef notyet - if (tp != NULL) - mutex_exit(&tp->t_mutex); -#endif + mutex_spin_exit(&tty_lock); mutex_exit(&proclist_mutex); if (LIST_EMPTY(&pgrp->pg_members)) @@ -969,7 +950,7 @@ pg_free(pid_t pg_id) last_free_pt = pg_id; pid_alloc_cnt--; } - pool_put(&pgrp_pool, pgrp); + pool_cache_put(pgrp_cache, pgrp); } /* @@ -993,6 +974,7 @@ pg_delete(pid_t pg_id) ss = pgrp->pg_session; /* Remove reference (if any) from tty to this process group */ + mutex_spin_enter(&tty_lock); ttyp = ss->s_ttyp; if (ttyp != NULL && ttyp->t_pgrp == pgrp) { ttyp->t_pgrp = NULL; @@ -1001,6 +983,7 @@ pg_delete(pid_t pg_id) panic("pg_delete: wrong session on terminal"); #endif } + mutex_spin_exit(&tty_lock); /* * The leading process group in a session is freed @@ -1032,7 +1015,7 @@ sessdelete(struct session *ss) * must be a 'zombie' pgrp by now. */ pg_free(ss->s_sid); - pool_put(&session_pool, ss); + pool_cache_put(session_cache, ss); } /* diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 57029446e49..cc658e8b501 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_resource.c,v 1.129 2007/12/22 01:14:54 yamt Exp $ */ +/* $NetBSD: kern_resource.c,v 1.130 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 1982, 1986, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.129 2007/12/22 01:14:54 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.130 2007/12/26 16:01:36 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,6 +68,19 @@ struct uihashhead *uihashtbl; u_long uihash; /* size of hash table - 1 */ kmutex_t uihashtbl_lock; +static pool_cache_t plimit_cache; +static pool_cache_t pstats_cache; + +void +resource_init(void) +{ + + plimit_cache = pool_cache_init(sizeof(struct plimit), 0, 0, 0, + "plimitpl", NULL, IPL_NONE, NULL, NULL, NULL); + pstats_cache = pool_cache_init(sizeof(struct pstats), 0, 0, 0, + "pstatspl", NULL, IPL_NONE, NULL, NULL, NULL); +} + /* * Resource controls and accounting. */ @@ -524,7 +537,7 @@ lim_copy(struct plimit *lim) char *corename; size_t alen, len; - newlim = pool_get(&plimit_pool, PR_WAITOK); + newlim = pool_cache_get(plimit_cache, PR_WAITOK); mutex_init(&newlim->pl_lock, MUTEX_DEFAULT, IPL_NONE); newlim->pl_flags = 0; newlim->pl_refcnt = 1; @@ -622,7 +635,7 @@ limfree(struct plimit *lim) free(lim->pl_corename, M_TEMP); sv_lim = lim->pl_sv_limit; mutex_destroy(&lim->pl_lock); - pool_put(&plimit_pool, lim); + pool_cache_put(plimit_cache, lim); } while ((lim = sv_lim) != NULL); } @@ -632,7 +645,7 @@ pstatscopy(struct pstats *ps) struct pstats *newps; - newps = pool_get(&pstats_pool, PR_WAITOK); + newps = pool_cache_get(pstats_cache, PR_WAITOK); memset(&newps->pstat_startzero, 0, (unsigned) ((char *)&newps->pstat_endzero - @@ -649,7 +662,7 @@ void pstatsfree(struct pstats *ps) { - pool_put(&pstats_pool, ps); + pool_cache_put(pstats_cache, ps); } /* diff --git a/sys/kern/subr_lockdebug.c b/sys/kern/subr_lockdebug.c index b05db11d0d3..a521d805ed5 100644 --- a/sys/kern/subr_lockdebug.c +++ b/sys/kern/subr_lockdebug.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_lockdebug.c,v 1.23 2007/12/08 15:00:13 ad Exp $ */ +/* $NetBSD: subr_lockdebug.c,v 1.24 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_lockdebug.c,v 1.23 2007/12/08 15:00:13 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_lockdebug.c,v 1.24 2007/12/26 16:01:36 ad Exp $"); #include "opt_ddb.h" @@ -673,6 +673,9 @@ lockdebug_mem_check(const char *func, void *base, size_t sz) lockdebuglk_t *lk; int s; + if (panicstr != NULL) + return; + s = lockdebug_lock_rd(&ld_tree_lk); ld = (lockdebug_t *)rb_tree_find_node_geq(&ld_rb_tree, base); if (ld != NULL) { diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c index 04341f66058..7f999e61947 100644 --- a/sys/kern/subr_pool.c +++ b/sys/kern/subr_pool.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_pool.c,v 1.144 2007/12/22 04:31:34 yamt Exp $ */ +/* $NetBSD: subr_pool.c,v 1.145 2007/12/26 16:01:36 ad Exp $ */ /*- * Copyright (c) 1997, 1999, 2000, 2002, 2007 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.144 2007/12/22 04:31:34 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.145 2007/12/26 16:01:36 ad Exp $"); #include "opt_ddb.h" #include "opt_pool.h" @@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.144 2007/12/22 04:31:34 yamt Exp $") #include <sys/lockdebug.h> #include <sys/xcall.h> #include <sys/cpu.h> +#include <sys/atomic.h> #include <uvm/uvm.h> @@ -76,11 +77,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.144 2007/12/22 04:31:34 yamt Exp $") */ /* List of all pools */ -LIST_HEAD(,pool) pool_head = LIST_HEAD_INITIALIZER(pool_head); - -/* List of all caches. */ -LIST_HEAD(,pool_cache) pool_cache_head = - LIST_HEAD_INITIALIZER(pool_cache_head); +TAILQ_HEAD(,pool) pool_head = TAILQ_HEAD_INITIALIZER(pool_head); /* Private pool for page header structures */ #define PHPOOL_MAX 8 @@ -186,6 +183,13 @@ static struct pool pcg_large_pool; static struct pool cache_pool; static struct pool cache_cpu_pool; +/* List of all caches. */ +TAILQ_HEAD(,pool_cache) pool_cache_head = + TAILQ_HEAD_INITIALIZER(pool_cache_head); + +int pool_cache_disable; + + static pool_cache_cpu_t *pool_cache_put_slow(pool_cache_cpu_t *, int *, void *, paddr_t); static pool_cache_cpu_t *pool_cache_get_slow(pool_cache_cpu_t *, int *, @@ -626,9 +630,7 @@ void pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags, const char *wchan, struct pool_allocator *palloc, int ipl) { -#ifdef DEBUG struct pool *pp1; -#endif size_t trysize, phsize; int off, slack; @@ -637,7 +639,7 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags, * Check that the pool hasn't already been initialised and * added to the list of all pools. */ - LIST_FOREACH(pp1, &pool_head, pr_poollist) { + TAILQ_FOREACH(pp1, &pool_head, pr_poollist) { if (pp == pp1) panic("pool_init: pool %s already initialised", wchan); @@ -863,20 +865,26 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags, "pcglarge", &pool_allocator_meta, IPL_VM); } - if (__predict_true(!cold)) { - /* Insert into the list of all pools. */ + /* Insert into the list of all pools. */ + if (__predict_true(!cold)) mutex_enter(&pool_head_lock); - LIST_INSERT_HEAD(&pool_head, pp, pr_poollist); + TAILQ_FOREACH(pp1, &pool_head, pr_poollist) { + if (strcmp(pp1->pr_wchan, pp->pr_wchan) > 0) + break; + } + if (pp1 == NULL) + TAILQ_INSERT_TAIL(&pool_head, pp, pr_poollist); + else + TAILQ_INSERT_BEFORE(pp1, pp, pr_poollist); + if (__predict_true(!cold)) mutex_exit(&pool_head_lock); /* Insert this into the list of pools using this allocator. */ + if (__predict_true(!cold)) mutex_enter(&palloc->pa_lock); - TAILQ_INSERT_TAIL(&palloc->pa_list, pp, pr_alloc_list); + TAILQ_INSERT_TAIL(&palloc->pa_list, pp, pr_alloc_list); + if (__predict_true(!cold)) mutex_exit(&palloc->pa_lock); - } else { - LIST_INSERT_HEAD(&pool_head, pp, pr_poollist); - TAILQ_INSERT_TAIL(&palloc->pa_list, pp, pr_alloc_list); - } pool_reclaim_register(pp); } @@ -894,7 +902,7 @@ pool_destroy(struct pool *pp) mutex_enter(&pool_head_lock); while (pp->pr_refcnt != 0) cv_wait(&pool_busy, &pool_head_lock); - LIST_REMOVE(pp, pr_poollist); + TAILQ_REMOVE(&pool_head, pp, pr_poollist); if (drainpp == pp) drainpp = NULL; mutex_exit(&pool_head_lock); @@ -1701,7 +1709,7 @@ pool_drain_start(struct pool **ppp, uint64_t *wp) { struct pool *pp; - KASSERT(!LIST_EMPTY(&pool_head)); + KASSERT(!TAILQ_EMPTY(&pool_head)); pp = NULL; @@ -1709,11 +1717,11 @@ pool_drain_start(struct pool **ppp, uint64_t *wp) mutex_enter(&pool_head_lock); do { if (drainpp == NULL) { - drainpp = LIST_FIRST(&pool_head); + drainpp = TAILQ_FIRST(&pool_head); } if (drainpp != NULL) { pp = drainpp; - drainpp = LIST_NEXT(pp, pr_poollist); + drainpp = TAILQ_NEXT(pp, pr_poollist); } /* * Skip completely idle pools. We depend on at least @@ -1769,7 +1777,7 @@ pool_printall(const char *modif, void (*pr)(const char *, ...)) { struct pool *pp; - LIST_FOREACH(pp, &pool_head, pr_poollist) { + TAILQ_FOREACH(pp, &pool_head, pr_poollist) { pool_printit(pp, modif, pr); } } @@ -2059,6 +2067,7 @@ pool_cache_bootstrap(pool_cache_t pc, size_t size, u_int align, void *arg) { CPU_INFO_ITERATOR cii; + pool_cache_t pc1; struct cpu_info *ci; struct pool *pp; @@ -2115,18 +2124,23 @@ pool_cache_bootstrap(pool_cache_t pc, size_t size, u_int align, pool_cache_cpu_init1(ci, pc); } } - - if (__predict_true(!cold)) { - mutex_enter(&pp->pr_lock); - pp->pr_cache = pc; - mutex_exit(&pp->pr_lock); + + /* Add to list of all pools. */ + if (__predict_true(!cold)) mutex_enter(&pool_head_lock); - LIST_INSERT_HEAD(&pool_cache_head, pc, pc_cachelist); - mutex_exit(&pool_head_lock); - } else { - pp->pr_cache = pc; - LIST_INSERT_HEAD(&pool_cache_head, pc, pc_cachelist); + TAILQ_FOREACH(pc1, &pool_cache_head, pc_cachelist) { + if (strcmp(pc1->pc_pool.pr_wchan, pc->pc_pool.pr_wchan) > 0) + break; } + if (pc1 == NULL) + TAILQ_INSERT_TAIL(&pool_cache_head, pc, pc_cachelist); + else + TAILQ_INSERT_BEFORE(pc1, pc, pc_cachelist); + if (__predict_true(!cold)) + mutex_exit(&pool_head_lock); + + membar_sync(); + pp->pr_cache = pc; } /* @@ -2146,7 +2160,7 @@ pool_cache_destroy(pool_cache_t pc) mutex_enter(&pool_head_lock); while (pc->pc_refcnt != 0) cv_wait(&pool_busy, &pool_head_lock); - LIST_REMOVE(pc, pc_cachelist); + TAILQ_REMOVE(&pool_cache_head, pc, pc_cachelist); mutex_exit(&pool_head_lock); /* First, invalidate the entire cache. */ @@ -2237,7 +2251,7 @@ pool_cache_cpu_init(struct cpu_info *ci) pool_cache_t pc; mutex_enter(&pool_head_lock); - LIST_FOREACH(pc, &pool_cache_head, pc_cachelist) { + TAILQ_FOREACH(pc, &pool_cache_head, pc_cachelist) { pc->pc_refcnt++; mutex_exit(&pool_head_lock); @@ -2979,7 +2993,7 @@ pool_whatis(uintptr_t addr, void (*pr)(const char *, ...)) { struct pool *pp; - LIST_FOREACH(pp, &pool_head, pr_poollist) { + TAILQ_FOREACH(pp, &pool_head, pr_poollist) { struct pool_item_header *ph; uintptr_t item; bool allocated = true; diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 05ef5d52bd7..a90d7b60bf9 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_pipe.c,v 1.89 2007/12/20 23:03:11 dsl Exp $ */ +/* $NetBSD: sys_pipe.c,v 1.90 2007/12/26 16:01:37 ad Exp $ */ /*- * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. @@ -83,7 +83,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.89 2007/12/20 23:03:11 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.90 2007/12/26 16:01:37 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -104,12 +104,13 @@ __KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.89 2007/12/20 23:03:11 dsl Exp $"); #include <sys/select.h> #include <sys/mount.h> #include <sys/syscallargs.h> -#include <uvm/uvm.h> #include <sys/sysctl.h> #include <sys/kauth.h> - +#include <sys/atomic.h> #include <sys/pipe.h> +#include <uvm/uvm.h> + /* * Use this define if you want to disable *fancy* VM things. Expect an * approx 30% decrease in transfer rate. @@ -136,6 +137,15 @@ static const struct fileops pipeops = { }; /* + * Single mutex shared between both ends of the pipe. + */ + +struct pipe_mutex { + kmutex_t pm_mutex; + u_int pm_refcnt; +}; + +/* * Default pipe buffer size(s), this can be kind-of large now because pipe * space is pageable. The pipe code will try to maintain locality of * reference for performance reasons, so small amounts of outstanding I/O @@ -149,32 +159,32 @@ static const struct fileops pipeops = { * is there so that on large systems, we don't exhaust it. */ #define MAXPIPEKVA (8*1024*1024) -static int maxpipekva = MAXPIPEKVA; +static u_int maxpipekva = MAXPIPEKVA; /* * Limit for direct transfers, we cannot, of course limit * the amount of kva for pipes in general though. */ #define LIMITPIPEKVA (16*1024*1024) -static int limitpipekva = LIMITPIPEKVA; +static u_int limitpipekva = LIMITPIPEKVA; /* * Limit the number of "big" pipes */ #define LIMITBIGPIPES 32 -static int maxbigpipes = LIMITBIGPIPES; -static int nbigpipe = 0; +static u_int maxbigpipes = LIMITBIGPIPES; +static u_int nbigpipe = 0; /* * Amount of KVA consumed by pipe buffers. */ -static int amountpipekva = 0; +static u_int amountpipekva = 0; MALLOC_DEFINE(M_PIPE, "pipe", "Pipe structures"); static void pipeclose(struct file *fp, struct pipe *pipe); static void pipe_free_kmem(struct pipe *pipe); -static int pipe_create(struct pipe **pipep, int allockva); +static int pipe_create(struct pipe **pipep, int allockva, struct pipe_mutex *); static int pipelock(struct pipe *pipe, int catch); static inline void pipeunlock(struct pipe *pipe); static void pipeselwakeup(struct pipe *pipe, struct pipe *sigp, int code); @@ -189,17 +199,48 @@ static int pipe_loan_alloc(struct pipe *, int); static void pipe_loan_free(struct pipe *); #endif /* PIPE_NODIRECT */ -static krwlock_t pipe_peer_lock; +static int pipe_mutex_ctor(void *, void *, int); +static void pipe_mutex_dtor(void *, void *); + static pool_cache_t pipe_cache; +static pool_cache_t pipe_mutex_cache; void pipe_init(void) { + size_t size; pipe_cache = pool_cache_init(sizeof(struct pipe), 0, 0, 0, "pipepl", NULL, IPL_NONE, NULL, NULL, NULL); KASSERT(pipe_cache != NULL); - rw_init(&pipe_peer_lock); + + size = (sizeof(struct pipe_mutex) + (CACHE_LINE_SIZE - 1)) & + (CACHE_LINE_SIZE - 1); + pipe_mutex_cache = pool_cache_init(size, CACHE_LINE_SIZE, + 0, 0, "pipemtxpl", NULL, IPL_NONE, pipe_mutex_ctor, + pipe_mutex_dtor, NULL); + KASSERT(pipe_cache != NULL); +} + +static int +pipe_mutex_ctor(void *arg, void *obj, int flag) +{ + struct pipe_mutex *pm = obj; + + mutex_init(&pm->pm_mutex, MUTEX_DEFAULT, IPL_NONE); + pm->pm_refcnt = 0; + + return 0; +} + +static void +pipe_mutex_dtor(void *arg, void *obj) +{ + struct pipe_mutex *pm = obj; + + KASSERT(pm->pm_refcnt == 0); + + mutex_destroy(&pm->pm_mutex); } /* @@ -212,10 +253,14 @@ sys_pipe(struct lwp *l, const void *v, register_t *retval) { struct file *rf, *wf; struct pipe *rpipe, *wpipe; + struct pipe_mutex *mutex; int fd, error; rpipe = wpipe = NULL; - if (pipe_create(&rpipe, 1) || pipe_create(&wpipe, 0)) { + mutex = pool_cache_get(pipe_mutex_cache, PR_WAITOK); + if (mutex == NULL) + return (ENOMEM); + if (pipe_create(&rpipe, 1, mutex) || pipe_create(&wpipe, 0, mutex)) { pipeclose(NULL, rpipe); pipeclose(NULL, wpipe); return (ENFILE); @@ -292,7 +337,7 @@ pipespace(struct pipe *pipe, int size) pipe->pipe_buffer.in = 0; pipe->pipe_buffer.out = 0; pipe->pipe_buffer.cnt = 0; - amountpipekva += pipe->pipe_buffer.size; + atomic_add_int(&amountpipekva, pipe->pipe_buffer.size); return (0); } @@ -300,12 +345,13 @@ pipespace(struct pipe *pipe, int size) * Initialize and allocate VM and memory for pipe. */ static int -pipe_create(struct pipe **pipep, int allockva) +pipe_create(struct pipe **pipep, int allockva, struct pipe_mutex *mutex) { struct pipe *pipe; int error; pipe = *pipep = pool_cache_get(pipe_cache, PR_WAITOK); + mutex->pm_refcnt++; /* Initialize */ memset(pipe, 0, sizeof(struct pipe)); @@ -314,7 +360,7 @@ pipe_create(struct pipe **pipep, int allockva) getmicrotime(&pipe->pipe_ctime); pipe->pipe_atime = pipe->pipe_ctime; pipe->pipe_mtime = pipe->pipe_ctime; - mutex_init(&pipe->pipe_lock, MUTEX_DEFAULT, IPL_NONE); + pipe->pipe_lock = &mutex->pm_mutex; cv_init(&pipe->pipe_cv, "pipe"); cv_init(&pipe->pipe_lkcv, "pipelk"); selinit(&pipe->pipe_sel); @@ -336,21 +382,19 @@ pipelock(struct pipe *pipe, int catch) { int error; - KASSERT(mutex_owned(&pipe->pipe_lock)); + KASSERT(mutex_owned(pipe->pipe_lock)); while (pipe->pipe_state & PIPE_LOCKFL) { pipe->pipe_state |= PIPE_LWANT; if (catch) { - error = cv_wait_sig(&pipe->pipe_lkcv, - &pipe->pipe_lock); + error = cv_wait_sig(&pipe->pipe_lkcv, pipe->pipe_lock); if (error != 0) return error; } else - cv_wait(&pipe->pipe_lkcv, &pipe->pipe_lock); + cv_wait(&pipe->pipe_lkcv, pipe->pipe_lock); } pipe->pipe_state |= PIPE_LOCKFL; - mutex_exit(&pipe->pipe_lock); return 0; } @@ -423,7 +467,7 @@ pipe_read(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred, size_t size; size_t ocnt; - mutex_enter(&rpipe->pipe_lock); + mutex_enter(rpipe->pipe_lock); ++rpipe->pipe_busy; ocnt = bp->cnt; @@ -443,7 +487,9 @@ again: if (size > uio->uio_resid) size = uio->uio_resid; + mutex_exit(rpipe->pipe_lock); error = uiomove((char *)bp->buffer + bp->out, size, uio); + mutex_enter(rpipe->pipe_lock); if (error) break; @@ -466,9 +512,6 @@ again: continue; } - /* Lock to see up-to-date value of pipe_status. */ - mutex_enter(&rpipe->pipe_lock); - #ifndef PIPE_NODIRECT if ((rpipe->pipe_state & PIPE_DIRECTR) != 0) { /* @@ -477,24 +520,23 @@ again: void * va; KASSERT(rpipe->pipe_state & PIPE_DIRECTW); - mutex_exit(&rpipe->pipe_lock); size = rpipe->pipe_map.cnt; if (size > uio->uio_resid) size = uio->uio_resid; va = (char *)rpipe->pipe_map.kva + rpipe->pipe_map.pos; + mutex_exit(rpipe->pipe_lock); error = uiomove(va, size, uio); + mutex_enter(rpipe->pipe_lock); if (error) break; nread += size; rpipe->pipe_map.pos += size; rpipe->pipe_map.cnt -= size; if (rpipe->pipe_map.cnt == 0) { - mutex_enter(&rpipe->pipe_lock); rpipe->pipe_state &= ~PIPE_DIRECTR; cv_broadcast(&rpipe->pipe_cv); - mutex_exit(&rpipe->pipe_lock); } continue; } @@ -502,25 +544,20 @@ again: /* * Break if some data was read. */ - if (nread > 0) { - mutex_exit(&rpipe->pipe_lock); + if (nread > 0) break; - } /* * detect EOF condition * read returns 0 on EOF, no need to set error */ - if (rpipe->pipe_state & PIPE_EOF) { - mutex_exit(&rpipe->pipe_lock); + if (rpipe->pipe_state & PIPE_EOF) break; - } /* * don't block on non-blocking I/O */ if (fp->f_flag & FNONBLOCK) { - mutex_exit(&rpipe->pipe_lock); error = EAGAIN; break; } @@ -553,7 +590,7 @@ again: /* Now wait until the pipe is filled */ rpipe->pipe_state |= PIPE_WANTR; - error = cv_wait_sig(&rpipe->pipe_cv, &rpipe->pipe_lock); + error = cv_wait_sig(&rpipe->pipe_cv, rpipe->pipe_lock); if (error != 0) goto unlocked_error; goto again; @@ -561,8 +598,6 @@ again: if (error == 0) getmicrotime(&rpipe->pipe_atime); - - mutex_enter(&rpipe->pipe_lock); pipeunlock(rpipe); unlocked_error: @@ -595,7 +630,7 @@ unlocked_error: rpipe->pipe_state &= ~PIPE_SIGNALR; } - mutex_exit(&rpipe->pipe_lock); + mutex_exit(rpipe->pipe_lock); return (error); } @@ -614,7 +649,7 @@ pipe_loan_alloc(struct pipe *wpipe, int npages) if (wpipe->pipe_map.kva == 0) return (ENOMEM); - amountpipekva += len; + atomic_add_int(&amountpipekva, len); wpipe->pipe_map.npages = npages; wpipe->pipe_map.pgs = malloc(npages * sizeof(struct vm_page *), M_PIPE, M_WAITOK); @@ -632,7 +667,7 @@ pipe_loan_free(struct pipe *wpipe) len = (vsize_t)wpipe->pipe_map.npages << PAGE_SHIFT; uvm_km_free(kernel_map, wpipe->pipe_map.kva, len, UVM_KMF_VAONLY); wpipe->pipe_map.kva = 0; - amountpipekva -= len; + atomic_add_int(&amountpipekva, -len); free(wpipe->pipe_map.pgs, M_PIPE); wpipe->pipe_map.pgs = NULL; } @@ -656,8 +691,11 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) vsize_t blen, bcnt; voff_t bpos; + KASSERT(mutex_owned(wpipe->pipe_lock)); KASSERT(wpipe->pipe_map.cnt == 0); + mutex_exit(wpipe->pipe_lock); + /* * Handle first PIPE_CHUNK_SIZE bytes of buffer. Deal with buffers * not aligned to PAGE_SIZE. @@ -687,8 +725,10 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) /* Allocate new kva. */ if (wpipe->pipe_map.kva == 0) { error = pipe_loan_alloc(wpipe, npages); - if (error) + if (error) { + mutex_enter(wpipe->pipe_lock); return (error); + } } /* Loan the write buffer memory from writer process */ @@ -697,6 +737,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) pgs, UVM_LOAN_TOPAGE); if (error) { pipe_loan_free(wpipe); + mutex_enter(wpipe->pipe_lock); return (ENOMEM); /* so that caller fallback to ordinary write */ } @@ -716,7 +757,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) * have to wait until the pipe is drained. Release the * pipe lock while we wait. */ - mutex_enter(&wpipe->pipe_lock); + mutex_enter(wpipe->pipe_lock); wpipe->pipe_state |= PIPE_DIRECTW; pipeunlock(wpipe); @@ -727,7 +768,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) } wpipe->pipe_state |= PIPE_WANTW; - error = cv_wait_sig(&wpipe->pipe_cv, &wpipe->pipe_lock); + error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock); if (error == 0 && wpipe->pipe_state & PIPE_EOF) error = EPIPE; } @@ -742,7 +783,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) cv_broadcast(&wpipe->pipe_cv); } pipeselwakeup(wpipe, wpipe, POLL_IN); - error = cv_wait_sig(&wpipe->pipe_cv, &wpipe->pipe_lock); + error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock); if (error == 0 && wpipe->pipe_state & PIPE_EOF) error = EPIPE; } @@ -752,6 +793,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) /* Acquire the pipe lock and cleanup */ (void)pipelock(wpipe, 0); + mutex_exit(wpipe->pipe_lock); if (pgs != NULL) { pmap_kremove(wpipe->pipe_map.kva, blen); @@ -760,6 +802,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) if (error || amountpipekva > maxpipekva) pipe_loan_free(wpipe); + mutex_enter(wpipe->pipe_lock); if (error) { pipeselwakeup(wpipe, wpipe, POLL_ERR); @@ -772,6 +815,7 @@ pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio) if (wpipe->pipe_map.cnt == bcnt) { wpipe->pipe_map.cnt = 0; cv_broadcast(&wpipe->pipe_cv); + mutex_exit(wpipe->pipe_lock); return (error); } @@ -802,32 +846,21 @@ pipe_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred, /* We want to write to our peer */ rpipe = (struct pipe *) fp->f_data; - -retry: error = 0; - mutex_enter(&rpipe->pipe_lock); + + mutex_enter(rpipe->pipe_lock); wpipe = rpipe->pipe_peer; /* * Detect loss of pipe read side, issue SIGPIPE if lost. */ - if (wpipe == NULL) - error = EPIPE; - else if (mutex_tryenter(&wpipe->pipe_lock) == 0) { - /* Deal with race for peer */ - mutex_exit(&rpipe->pipe_lock); - /* XXX Might be about to deadlock w/kernel_lock. */ - yield(); - goto retry; + if (wpipe == NULL) { + mutex_exit(rpipe->pipe_lock); + return EPIPE; } else if ((wpipe->pipe_state & PIPE_EOF) != 0) { - mutex_exit(&wpipe->pipe_lock); - error = EPIPE; + mutex_exit(rpipe->pipe_lock); + return EPIPE; } - - mutex_exit(&rpipe->pipe_lock); - if (error != 0) - return (error); - ++wpipe->pipe_busy; /* Aquire the long-term pipe lock */ @@ -838,7 +871,7 @@ retry: wpipe->pipe_state &= ~(PIPE_WANTCLOSE | PIPE_WANTR); cv_broadcast(&wpipe->pipe_cv); } - mutex_exit(&wpipe->pipe_lock); + mutex_exit(rpipe->pipe_lock); return (error); } @@ -855,7 +888,7 @@ retry: (bp->size <= PIPE_SIZE) && (bp->cnt == 0)) { if (pipespace(wpipe, BIG_PIPE_SIZE) == 0) - nbigpipe++; + atomic_inc_uint(&nbigpipe); } while (uio->uio_resid) { @@ -871,15 +904,13 @@ retry: * We break out if a signal occurs or the reader goes away. */ while (error == 0 && wpipe->pipe_state & PIPE_DIRECTW) { - mutex_enter(&wpipe->pipe_lock); if (wpipe->pipe_state & PIPE_WANTR) { wpipe->pipe_state &= ~PIPE_WANTR; cv_broadcast(&wpipe->pipe_cv); } pipeunlock(wpipe); error = cv_wait_sig(&wpipe->pipe_cv, - &wpipe->pipe_lock); - + wpipe->pipe_lock); (void)pipelock(wpipe, 0); if (wpipe->pipe_state & PIPE_EOF) error = EPIPE; @@ -946,6 +977,7 @@ retry: segsize = size; /* Transfer first segment */ + mutex_exit(wpipe->pipe_lock); error = uiomove((char *)bp->buffer + bp->in, segsize, uio); @@ -963,6 +995,7 @@ retry: error = uiomove(bp->buffer, size - segsize, uio); } + mutex_enter(wpipe->pipe_lock); if (error) break; @@ -984,12 +1017,10 @@ retry: /* * If the "read-side" has been blocked, wake it up now. */ - mutex_enter(&wpipe->pipe_lock); if (wpipe->pipe_state & PIPE_WANTR) { wpipe->pipe_state &= ~PIPE_WANTR; cv_broadcast(&wpipe->pipe_cv); } - mutex_exit(&wpipe->pipe_lock); /* * don't block on non-blocking I/O @@ -1006,11 +1037,9 @@ retry: if (bp->cnt) pipeselwakeup(wpipe, wpipe, POLL_OUT); - mutex_enter(&wpipe->pipe_lock); pipeunlock(wpipe); wpipe->pipe_state |= PIPE_WANTW; - error = cv_wait_sig(&wpipe->pipe_cv, - &wpipe->pipe_lock); + error = cv_wait_sig(&wpipe->pipe_cv, wpipe->pipe_lock); (void)pipelock(wpipe, 0); if (error != 0) break; @@ -1025,7 +1054,6 @@ retry: } } - mutex_enter(&wpipe->pipe_lock); --wpipe->pipe_busy; if ((wpipe->pipe_busy == 0) && (wpipe->pipe_state & PIPE_WANTCLOSE)) { wpipe->pipe_state &= ~(PIPE_WANTCLOSE | PIPE_WANTR); @@ -1064,7 +1092,7 @@ retry: wpipe->pipe_state |= PIPE_SIGNALR; pipeunlock(wpipe); - mutex_exit(&wpipe->pipe_lock); + mutex_exit(wpipe->pipe_lock); return (error); } @@ -1083,46 +1111,43 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l) return (0); case FIOASYNC: - mutex_enter(&pipe->pipe_lock); + mutex_enter(pipe->pipe_lock); if (*(int *)data) { pipe->pipe_state |= PIPE_ASYNC; } else { pipe->pipe_state &= ~PIPE_ASYNC; } - mutex_exit(&pipe->pipe_lock); + mutex_exit(pipe->pipe_lock); return (0); case FIONREAD: - mutex_enter(&pipe->pipe_lock); + mutex_enter(pipe->pipe_lock); #ifndef PIPE_NODIRECT if (pipe->pipe_state & PIPE_DIRECTW) *(int *)data = pipe->pipe_map.cnt; else #endif *(int *)data = pipe->pipe_buffer.cnt; - mutex_exit(&pipe->pipe_lock); + mutex_exit(pipe->pipe_lock); return (0); case FIONWRITE: /* Look at other side */ - rw_enter(&pipe_peer_lock, RW_READER); pipe = pipe->pipe_peer; - mutex_enter(&pipe->pipe_lock); + mutex_enter(pipe->pipe_lock); #ifndef PIPE_NODIRECT if (pipe->pipe_state & PIPE_DIRECTW) *(int *)data = pipe->pipe_map.cnt; else #endif *(int *)data = pipe->pipe_buffer.cnt; - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return (0); case FIONSPACE: /* Look at other side */ - rw_enter(&pipe_peer_lock, RW_READER); pipe = pipe->pipe_peer; - mutex_enter(&pipe->pipe_lock); + mutex_enter(pipe->pipe_lock); #ifndef PIPE_NODIRECT /* * If we're in direct-mode, we don't really have a @@ -1135,8 +1160,7 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l) #endif *(int *)data = pipe->pipe_buffer.size - pipe->pipe_buffer.cnt; - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return (0); case TIOCSPGRP: @@ -1159,16 +1183,8 @@ pipe_poll(struct file *fp, int events, struct lwp *l) int eof = 0; int revents = 0; -retry: - mutex_enter(&rpipe->pipe_lock); + mutex_enter(rpipe->pipe_lock); wpipe = rpipe->pipe_peer; - if (wpipe != NULL && mutex_tryenter(&wpipe->pipe_lock) == 0) { - /* Deal with race for peer */ - mutex_exit(&rpipe->pipe_lock); - /* XXX Might be about to deadlock w/kernel_lock. */ - yield(); - goto retry; - } if (events & (POLLIN | POLLRDNORM)) if ((rpipe->pipe_buffer.cnt > 0) || @@ -1179,7 +1195,6 @@ retry: revents |= events & (POLLIN | POLLRDNORM); eof |= (rpipe->pipe_state & PIPE_EOF); - mutex_exit(&rpipe->pipe_lock); if (wpipe == NULL) revents |= events & (POLLOUT | POLLWRNORM); @@ -1193,7 +1208,6 @@ retry: revents |= events & (POLLOUT | POLLWRNORM); eof |= (wpipe->pipe_state & PIPE_EOF); - mutex_exit(&wpipe->pipe_lock); } if (wpipe == NULL || eof) @@ -1206,6 +1220,7 @@ retry: if (events & (POLLOUT | POLLWRNORM)) selrecord(l, &wpipe->pipe_sel); } + mutex_exit(rpipe->pipe_lock); return (revents); } @@ -1215,8 +1230,6 @@ pipe_stat(struct file *fp, struct stat *ub, struct lwp *l) { struct pipe *pipe = (struct pipe *)fp->f_data; - rw_enter(&pipe_peer_lock, RW_READER); - memset((void *)ub, 0, sizeof(*ub)); ub->st_mode = S_IFIFO | S_IRUSR | S_IWUSR; ub->st_blksize = pipe->pipe_buffer.size; @@ -1230,8 +1243,6 @@ pipe_stat(struct file *fp, struct stat *ub, struct lwp *l) ub->st_uid = kauth_cred_geteuid(fp->f_cred); ub->st_gid = kauth_cred_getegid(fp->f_cred); - rw_exit(&pipe_peer_lock); - /* * Left as 0: st_dev, st_ino, st_nlink, st_rdev, st_flags, st_gen. * XXX (st_dev, st_ino) should be unique. @@ -1256,8 +1267,8 @@ pipe_free_kmem(struct pipe *pipe) if (pipe->pipe_buffer.buffer != NULL) { if (pipe->pipe_buffer.size > PIPE_SIZE) - --nbigpipe; - amountpipekva -= pipe->pipe_buffer.size; + atomic_dec_uint(&nbigpipe); + atomic_add_int(&amountpipekva, -pipe->pipe_buffer.size); uvm_km_free(kernel_map, (vaddr_t)pipe->pipe_buffer.buffer, pipe->pipe_buffer.size, UVM_KMF_PAGEABLE); @@ -1280,15 +1291,14 @@ pipe_free_kmem(struct pipe *pipe) static void pipeclose(struct file *fp, struct pipe *pipe) { + struct pipe_mutex *mutex; struct pipe *ppipe; + u_int refcnt; if (pipe == NULL) return; - retry: - rw_enter(&pipe_peer_lock, RW_WRITER); - mutex_enter(&pipe->pipe_lock); - + mutex_enter(pipe->pipe_lock); pipeselwakeup(pipe, pipe, POLL_HUP); /* @@ -1297,17 +1307,10 @@ pipeclose(struct file *fp, struct pipe *pipe) */ pipe->pipe_state |= PIPE_EOF; if (pipe->pipe_busy) { - rw_exit(&pipe_peer_lock); while (pipe->pipe_busy) { cv_broadcast(&pipe->pipe_cv); pipe->pipe_state |= PIPE_WANTCLOSE; - cv_wait_sig(&pipe->pipe_cv, &pipe->pipe_lock); - } - if (!rw_tryenter(&pipe_peer_lock, RW_READER)) { - mutex_exit(&pipe->pipe_lock); - /* XXX Might be about to deadlock w/kernel_lock. */ - yield(); - goto retry; + cv_wait_sig(&pipe->pipe_cv, pipe->pipe_lock); } } @@ -1315,36 +1318,29 @@ pipeclose(struct file *fp, struct pipe *pipe) * Disconnect from peer */ if ((ppipe = pipe->pipe_peer) != NULL) { - /* Deal with race for peer */ - if (mutex_tryenter(&ppipe->pipe_lock) == 0) { - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); - /* XXX Might be about to deadlock w/kernel_lock. */ - yield(); - goto retry; - } pipeselwakeup(ppipe, ppipe, POLL_HUP); - ppipe->pipe_state |= PIPE_EOF; cv_broadcast(&ppipe->pipe_cv); ppipe->pipe_peer = NULL; - mutex_exit(&ppipe->pipe_lock); } KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0); - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex = (struct pipe_mutex *)pipe->pipe_lock; + refcnt = --(mutex->pm_refcnt); + KASSERT(refcnt == 0 || refcnt == 1); + mutex_exit(pipe->pipe_lock); /* * free resources */ pipe_free_kmem(pipe); - mutex_destroy(&pipe->pipe_lock); cv_destroy(&pipe->pipe_cv); cv_destroy(&pipe->pipe_lkcv); seldestroy(&pipe->pipe_sel); pool_cache_put(pipe_cache, pipe); + if (refcnt == 0) + pool_cache_put(pipe_mutex_cache, mutex); } static void @@ -1352,7 +1348,7 @@ filt_pipedetach(struct knote *kn) { struct pipe *pipe = (struct pipe *)kn->kn_fp->f_data; - rw_enter(&pipe_peer_lock, RW_READER); + mutex_enter(pipe->pipe_lock); switch(kn->kn_filter) { case EVFILT_WRITE: @@ -1361,7 +1357,7 @@ filt_pipedetach(struct knote *kn) /* if reader end already closed, just return */ if (pipe == NULL) { - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return; } @@ -1376,10 +1372,8 @@ filt_pipedetach(struct knote *kn) panic("filt_pipedetach: inconsistent knote"); #endif - mutex_enter(&pipe->pipe_lock); SLIST_REMOVE(&pipe->pipe_sel.sel_klist, kn, knote, kn_selnext); - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); } /*ARGSUSED*/ @@ -1390,8 +1384,7 @@ filt_piperead(struct knote *kn, long hint) struct pipe *wpipe; if ((hint & NOTE_SUBMIT) == 0) { - rw_enter(&pipe_peer_lock, RW_READER); - mutex_enter(&rpipe->pipe_lock); + mutex_enter(rpipe->pipe_lock); } wpipe = rpipe->pipe_peer; kn->kn_data = rpipe->pipe_buffer.cnt; @@ -1403,15 +1396,13 @@ filt_piperead(struct knote *kn, long hint) (wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { kn->kn_flags |= EV_EOF; if ((hint & NOTE_SUBMIT) == 0) { - mutex_exit(&rpipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(rpipe->pipe_lock); } return (1); } if ((hint & NOTE_SUBMIT) == 0) { - mutex_exit(&rpipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(rpipe->pipe_lock); } return (kn->kn_data > 0); } @@ -1424,8 +1415,7 @@ filt_pipewrite(struct knote *kn, long hint) struct pipe *wpipe; if ((hint & NOTE_SUBMIT) == 0) { - rw_enter(&pipe_peer_lock, RW_READER); - mutex_enter(&rpipe->pipe_lock); + mutex_enter(rpipe->pipe_lock); } wpipe = rpipe->pipe_peer; @@ -1433,8 +1423,7 @@ filt_pipewrite(struct knote *kn, long hint) kn->kn_data = 0; kn->kn_flags |= EV_EOF; if ((hint & NOTE_SUBMIT) == 0) { - mutex_exit(&rpipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(rpipe->pipe_lock); } return (1); } @@ -1443,8 +1432,7 @@ filt_pipewrite(struct knote *kn, long hint) kn->kn_data = 0; if ((hint & NOTE_SUBMIT) == 0) { - mutex_exit(&rpipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(rpipe->pipe_lock); } return (kn->kn_data >= PIPE_BUF); } @@ -1460,8 +1448,8 @@ pipe_kqfilter(struct file *fp, struct knote *kn) { struct pipe *pipe; - rw_enter(&pipe_peer_lock, RW_READER); pipe = (struct pipe *)kn->kn_fp->f_data; + mutex_enter(pipe->pipe_lock); switch (kn->kn_filter) { case EVFILT_READ: @@ -1472,20 +1460,18 @@ pipe_kqfilter(struct file *fp, struct knote *kn) pipe = pipe->pipe_peer; if (pipe == NULL) { /* other end of pipe has been closed */ - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return (EBADF); } break; default: - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return (EINVAL); } kn->kn_hook = pipe; - mutex_enter(&pipe->pipe_lock); SLIST_INSERT_HEAD(&pipe->pipe_sel.sel_klist, kn, kn_selnext); - mutex_exit(&pipe->pipe_lock); - rw_exit(&pipe_peer_lock); + mutex_exit(pipe->pipe_lock); return (0); } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 6403eb74b2c..bcf2e144a9b 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.208 2007/12/08 19:29:49 pooka Exp $ */ +/* $NetBSD: tty.c,v 1.209 2007/12/26 16:01:37 ad Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.208 2007/12/08 19:29:49 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.209 2007/12/26 16:01:37 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -315,14 +315,14 @@ ttyclose(struct tty *tp) tp->t_gen++; tp->t_pgrp = NULL; tp->t_state = 0; + sess = tp->t_session; + tp->t_session = NULL; mutex_spin_exit(&tty_lock); mutex_enter(&proclist_lock); - if ((sess = tp->t_session) != NULL) { - SESSRELE(tp->t_session); - tp->t_session = NULL; - } + if (sess != NULL) + SESSRELE(sess); mutex_exit(&proclist_lock); return (0); @@ -839,18 +839,18 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) case TIOCSETP: case TIOCSLTC: #endif - /* XXXSMP */ + mutex_spin_enter(&tty_lock); while (isbackground(curproc, tp) && p->p_pgrp->pg_jobc && (p->p_sflag & PS_PPWAIT) == 0 && !sigismasked(l, SIGTTOU)) { - mutex_spin_enter(&tty_lock); ttysig(tp, TTYSIG_PG1, SIGTTOU); error = ttysleep(tp, &lbolt, true, 0); - mutex_spin_exit(&tty_lock); if (error) { + mutex_spin_exit(&tty_lock); return (error); } } + mutex_spin_exit(&tty_lock); break; } @@ -1109,11 +1109,13 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) } case TIOCSCTTY: /* become controlling tty */ mutex_enter(&proclist_lock); + mutex_spin_enter(&tty_lock); /* Session ctty vnode pointer set in vnode layer. */ if (!SESS_LEADER(p) || ((p->p_session->s_ttyvp || tp->t_session) && (tp->t_session != p->p_session))) { + mutex_spin_exit(&tty_lock); mutex_exit(&proclist_lock); return (EPERM); } @@ -1131,16 +1133,18 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) tp->t_pgrp = p->p_pgrp; p->p_session->s_ttyp = tp; p->p_lflag |= PL_CONTROLT; + mutex_spin_exit(&tty_lock); mutex_exit(&proclist_lock); break; case FIOSETOWN: { /* set pgrp of tty */ pid_t pgid = *(int *)data; struct pgrp *pgrp; - if (tp->t_session != NULL && !isctty(p, tp)) - return (ENOTTY); - mutex_enter(&proclist_lock); + if (tp->t_session != NULL && !isctty(p, tp)) { + mutex_exit(&proclist_lock); + return (ENOTTY); + } if (pgid < 0) { pgrp = pg_find(-pgid, PFIND_LOCKED | PFIND_UNLOCK_FAIL); @@ -1158,16 +1162,20 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) mutex_exit(&proclist_lock); return (EPERM); } + mutex_spin_enter(&tty_lock); tp->t_pgrp = pgrp; + mutex_spin_exit(&tty_lock); mutex_exit(&proclist_lock); break; } case TIOCSPGRP: { /* set pgrp of tty */ struct pgrp *pgrp; - if (!isctty(p, tp)) - return (ENOTTY); mutex_enter(&proclist_lock); + if (!isctty(p, tp)) { + mutex_exit(&proclist_lock); + return (ENOTTY); + } pgrp = pg_find(*(int *)data, PFIND_LOCKED | PFIND_UNLOCK_FAIL); if (pgrp == NULL) return (EINVAL); @@ -1175,7 +1183,9 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) mutex_exit(&proclist_lock); return (EPERM); } + mutex_spin_enter(&tty_lock); tp->t_pgrp = pgrp; + mutex_spin_exit(&tty_lock); mutex_exit(&proclist_lock); break; } @@ -1622,7 +1632,7 @@ ttread(struct tty *tp, struct uio *uio, int flag) ttypend(tp); /* - * Hang process if it's in the background. XXXSMP + * Hang process if it's in the background. */ if (isbackground(p, tp)) { if (sigismember(&p->p_sigctx.ps_sigignore, SIGTTIN) || @@ -1883,9 +1893,8 @@ ttwrite(struct tty *tp, struct uio *uio, int flag) goto loop; } } - mutex_spin_exit(&tty_lock); /* - * Hang the process if it's in the background. XXXSMP + * Hang the process if it's in the background. */ p = curproc; if (isbackground(p, tp) && @@ -1894,9 +1903,9 @@ ttwrite(struct tty *tp, struct uio *uio, int flag) !sigismember(&curlwp->l_sigmask, SIGTTOU)) { if (p->p_pgrp->pg_jobc == 0) { error = EIO; + mutex_spin_exit(&tty_lock); goto out; } - mutex_spin_enter(&tty_lock); ttysig(tp, TTYSIG_PG1, SIGTTOU); error = ttysleep(tp, &lbolt, true, 0); mutex_spin_exit(&tty_lock); @@ -1904,6 +1913,8 @@ ttwrite(struct tty *tp, struct uio *uio, int flag) goto out; goto loop; } + mutex_spin_exit(&tty_lock); + /* * Process the user's data in at most OBUFSIZ chunks. Perform any * output translation. Keep track of high water mark, sleep on @@ -2268,7 +2279,6 @@ ttsetwater(struct tty *tp) /* * Report on state of foreground process group. * Call with tty lock held. - * XXXSMP locking. */ void ttyinfo(struct tty *tp, int fromsig) @@ -2322,6 +2332,7 @@ ttyinfo(struct tty *tp, int fromsig) } pctcpu += pick->p_pctcpu; + /* XXXXSMP order tty_lock -> p_smutex is bad */ mutex_enter(&pick->p_smutex); calcru(pick, &utime, &stime, NULL, NULL); mutex_exit(&pick->p_smutex); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 67a5496179e..349774fe2f6 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_syscalls.c,v 1.125 2007/12/20 23:03:13 dsl Exp $ */ +/* $NetBSD: uipc_syscalls.c,v 1.126 2007/12/26 16:01:37 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1990, 1993 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.125 2007/12/20 23:03:13 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.126 2007/12/26 16:01:37 ad Exp $"); #include "opt_pipe.h" @@ -538,7 +538,9 @@ do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags, MCLAIM(control, so->so_mowner); len = auio.uio_resid; + KERNEL_LOCK(1, NULL); error = (*so->so_send)(so, to, &auio, NULL, control, flags, l); + KERNEL_UNLOCK_ONE(NULL); /* Protocol is responsible for freeing 'control' */ control = NULL; @@ -816,8 +818,10 @@ do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from, len = auio.uio_resid; mp->msg_flags &= MSG_USERFLAGS; + KERNEL_LOCK(1, NULL); error = (*so->so_receive)(so, from, &auio, NULL, control, &mp->msg_flags); + KERNEL_UNLOCK_ONE(NULL); len -= auio.uio_resid; *retsize = len; if (error != 0 && len != 0 diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 457b9e62b72..1b3dbf6e24c 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.336 2007/12/24 15:04:19 ad Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.337 2007/12/26 16:01:37 ad Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.336 2007/12/24 15:04:19 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.337 2007/12/26 16:01:37 ad Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_43.h" @@ -260,7 +260,7 @@ mount_get_vfsops(const char *fstype, struct vfsops **vfsops) static int mount_domount(struct lwp *l, struct vnode **vpp, struct vfsops *vfsops, - const char *path, int flags, void *data, size_t *data_len) + const char *path, int flags, void *data, size_t *data_len, u_int recurse) { struct mount *mp = NULL; struct vnode *vp = *vpp; @@ -345,6 +345,7 @@ mount_domount(struct lwp *l, struct vnode **vpp, struct vfsops *vfsops, mutex_enter(&mountlist_lock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); mutex_exit(&mountlist_lock); + vn_restorerecurse(vp, recurse); VOP_UNLOCK(vp, 0); checkdirs(vp); if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0) @@ -434,6 +435,7 @@ do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type, struct vnode *vp; struct nameidata nd; void *data_buf = data; + u_int recurse; int error; /* @@ -448,7 +450,8 @@ do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type, * A lookup in VFS_MOUNT might result in an attempt to * lock this vnode again, so make the lock recursive. */ - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_SETRECURSE); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + recurse = vn_setrecurse(vp); if (vfsops == NULL) { if (flags & (MNT_GETARGS | MNT_UPDATE)) @@ -501,12 +504,14 @@ do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type, } else { /* Locking is handled internally in mount_domount(). */ error = mount_domount(l, &vp, vfsops, path, flags, data_buf, - &data_len); + &data_len, recurse); } done: - if (vp) - vput(vp); + if (vp != NULL) { + vn_restorerecurse(vp, recurse); + vput(vp); + } if (data_buf != data) free(data_buf, M_TEMP); return (error); @@ -751,7 +756,14 @@ sys_sync(struct lwp *l, const void *v, register_t *retval) if ((mp->mnt_flag & MNT_RDONLY) == 0) { asyncflag = mp->mnt_flag & MNT_ASYNC; mp->mnt_flag &= ~MNT_ASYNC; + /* XXXSMP hack, sync is slow. */ + if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { + KERNEL_LOCK(1, NULL); + } VFS_SYNC(mp, MNT_NOWAIT, l->l_cred); + if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { + KERNEL_UNLOCK_ONE(NULL); + } if (asyncflag) mp->mnt_flag |= MNT_ASYNC; } diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c index 1d5cb106285..dd515c2dca8 100644 --- a/sys/miscfs/procfs/procfs_vfsops.c +++ b/sys/miscfs/procfs/procfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vfsops.c,v 1.75 2007/11/26 19:02:16 pooka Exp $ */ +/* $NetBSD: procfs_vfsops.c,v 1.76 2007/12/26 16:01:37 ad Exp $ */ /* * Copyright (c) 1993 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.75 2007/11/26 19:02:16 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.76 2007/12/26 16:01:37 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -161,6 +161,7 @@ procfs_mount( else pmnt->pmnt_flags = 0; + mp->mnt_iflag |= IMNT_MPSAFE; return error; } diff --git a/sys/sys/file.h b/sys/sys/file.h index 1f8a1dfd0c2..9df5e8f7df8 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -1,4 +1,4 @@ -/* $NetBSD: file.h,v 1.60 2007/10/08 23:20:38 ad Exp $ */ +/* $NetBSD: file.h,v 1.61 2007/12/26 16:01:38 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -156,8 +156,8 @@ do { \ LIST_HEAD(filelist, file); extern struct filelist filehead; /* head of list of open files */ -extern int maxfiles; /* kernel limit on # of open files */ -extern int nfiles; /* actual number of open files */ +extern u_int maxfiles; /* kernel limit on # of open files */ +extern u_int nfiles; /* actual number of open files */ extern const struct fileops vnops; /* vnode operations for files */ diff --git a/sys/sys/lwp.h b/sys/sys/lwp.h index 5276ffc8198..027d6c6b6d9 100644 --- a/sys/sys/lwp.h +++ b/sys/sys/lwp.h @@ -1,4 +1,4 @@ -/* $NetBSD: lwp.h,v 1.74 2007/12/25 18:33:48 perry Exp $ */ +/* $NetBSD: lwp.h,v 1.75 2007/12/26 16:01:38 ad Exp $ */ /*- * Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc. @@ -85,7 +85,7 @@ struct lwp { struct bintime l_rtime; /* l: real time */ struct bintime l_stime; /* l: start time (while ONPROC) */ u_int l_swtime; /* l: time swapped in or out */ - int l_holdcnt; /* l: if non-zero, don't swap */ + u_int l_holdcnt; /* l: if non-zero, don't swap */ int l_biglocks; /* l: biglock count before sleep */ int l_class; /* l: scheduling class */ int l_kpriority; /* !: has kernel priority boost */ diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h index a507e258a46..d9882c9dc02 100644 --- a/sys/sys/pipe.h +++ b/sys/sys/pipe.h @@ -1,4 +1,4 @@ -/* $NetBSD: pipe.h,v 1.21 2007/03/12 21:31:03 ad Exp $ */ +/* $NetBSD: pipe.h,v 1.22 2007/12/26 16:01:38 ad Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -104,7 +104,7 @@ struct pipemapping { * Two of these are linked together to produce bi-directional pipes. */ struct pipe { - kmutex_t pipe_lock; /* pipe mutex */ + kmutex_t *pipe_lock; /* pipe mutex */ kcondvar_t pipe_cv; /* general synchronization */ kcondvar_t pipe_lkcv; /* locking */ struct pipebuf pipe_buffer; /* data storage */ diff --git a/sys/sys/pool.h b/sys/sys/pool.h index 790778ffbf0..7da0bcb1d89 100644 --- a/sys/sys/pool.h +++ b/sys/sys/pool.h @@ -1,4 +1,4 @@ -/* $NetBSD: pool.h,v 1.61 2007/12/24 16:45:16 ad Exp $ */ +/* $NetBSD: pool.h,v 1.62 2007/12/26 16:01:38 ad Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2000, 2007 The NetBSD Foundation, Inc. @@ -84,7 +84,7 @@ struct pool_allocator { LIST_HEAD(pool_pagelist,pool_item_header); struct pool { - LIST_ENTRY(pool) + TAILQ_ENTRY(pool) pr_poollist; struct pool_pagelist pr_emptypages; /* Empty pages */ @@ -227,7 +227,7 @@ struct pool_cache { /* Cache layer. */ kmutex_t pc_lock; /* locks cache layer */ - LIST_ENTRY(pool_cache) + TAILQ_ENTRY(pool_cache) pc_cachelist; /* entry on global cache list */ pcg_t *pc_emptygroups;/* list of empty cache groups */ pcg_t *pc_fullgroups; /* list of full cache groups */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index dbbb8904c25..cd774b2409b 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.264 2007/12/25 18:33:48 perry Exp $ */ +/* $NetBSD: proc.h,v 1.265 2007/12/26 16:01:38 ad Exp $ */ /*- * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. @@ -494,11 +494,6 @@ extern struct proc *initproc; /* Process slots for init, pager */ extern const struct proclist_desc proclists[]; -extern struct pool proc_pool; /* Memory pool for procs */ -extern struct pool pcred_pool; /* Memory pool for pcreds */ -extern struct pool plimit_pool; /* Memory pool for plimits */ -extern struct pool pstats_pool; /* memory pool for pstats */ -extern struct pool rusage_pool; /* Memory pool for rusages */ extern struct pool ptimer_pool; /* Memory pool for ptimers */ struct proc *p_find(pid_t, uint); /* Find process by id */ @@ -533,6 +528,7 @@ int do_sys_wait(struct lwp *, int *, int *, int, struct rusage *, int *); struct proc *proc_alloc(void); void proc0_init(void); void proc_free_pid(struct proc *); +void proc_free_mem(struct proc *); void exit_lwps(struct lwp *l); int fork1(struct lwp *, int, int, void *, size_t, void (*)(void *), void *, register_t *, struct proc **); diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index ed4cdd7f857..4df93e4224f 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -1,4 +1,4 @@ -/* $NetBSD: resourcevar.h,v 1.40 2007/09/29 12:22:30 dsl Exp $ */ +/* $NetBSD: resourcevar.h,v 1.41 2007/12/26 16:01:38 ad Exp $ */ /* * Copyright (c) 1991, 1993 @@ -132,6 +132,7 @@ void lim_addref(struct plimit *lim); void lim_privatise(struct proc *p, bool set_shared); void limfree(struct plimit *); +void resource_init(void); void ruadd(struct rusage *, struct rusage *); struct pstats *pstatscopy(struct pstats *); void pstatsfree(struct pstats *); diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index 85a00b0453e..e87d7b598b2 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -1,4 +1,4 @@ -/* $NetBSD: sockstat.c,v 1.10 2005/08/24 21:33:57 rpaulo Exp $ */ +/* $NetBSD: sockstat.c,v 1.11 2007/12/26 16:01:38 ad Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: sockstat.c,v 1.10 2005/08/24 21:33:57 rpaulo Exp $"); +__RCSID("$NetBSD: sockstat.c,v 1.11 2007/12/26 16:01:38 ad Exp $"); #endif #include <sys/param.h> @@ -99,7 +99,7 @@ struct sockitem { }; struct kinfo_file *flist; -int nfiles; +u_int nfiles; int pf_list, only, nonames; bitstr_t *portmap; diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index 9138e93716d..3c423a71376 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.156 2007/12/20 23:49:11 ad Exp $ */ +/* $NetBSD: vmstat.c,v 1.157 2007/12/26 16:01:39 ad Exp $ */ /*- * Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc. @@ -77,7 +77,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\n\ #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; #else -__RCSID("$NetBSD: vmstat.c,v 1.156 2007/12/20 23:49:11 ad Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.157 2007/12/26 16:01:39 ad Exp $"); #endif #endif /* not lint */ @@ -1177,17 +1177,17 @@ dopool(int verbose, int wide) int first, ovflw; void *addr; long total, inuse, this_total, this_inuse; - LIST_HEAD(,pool) pool_head; + TAILQ_HEAD(,pool) pool_head; struct pool pool, *pp = &pool; struct pool_allocator pa; char name[32], maxp[32]; kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); - addr = LIST_FIRST(&pool_head); + addr = TAILQ_FIRST(&pool_head); total = inuse = 0; - for (first = 1; addr != NULL; addr = LIST_NEXT(pp, pr_poollist) ) { + for (first = 1; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist) ) { deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed"); deref_kptr(pp->pr_alloc, &pa, sizeof(pa), "pool allocator trashed"); @@ -1283,7 +1283,7 @@ dopoolcache(void) { struct pool_cache pool_cache, *pc = &pool_cache; pool_cache_cpu_t cache_cpu, *cc = &cache_cpu; - LIST_HEAD(,pool) pool_head; + TAILQ_HEAD(,pool) pool_head; struct pool pool, *pp = &pool; char name[32]; uint64_t cpuhit, cpumiss, tot; @@ -1292,9 +1292,9 @@ dopoolcache(void) double p; kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); - addr = LIST_FIRST(&pool_head); + addr = TAILQ_FIRST(&pool_head); - for (first = 1; addr != NULL; addr = LIST_NEXT(pp, pr_poollist) ) { + for (first = 1; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist) ) { deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed"); if (pp->pr_cache == NULL) continue; |
