summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2007-12-26 16:01:34 +0000
committerad <ad@NetBSD.org>2007-12-26 16:01:34 +0000
commitea3f10f7e0bbec1b91020f8a5f122d418ab2fbcc (patch)
tree76b2e7de3e201fd39b888fe4985745e3d166aad8
parent890b62431b0627bd148b755191009d3d0b9ca813 (diff)
Merge more changes from vmlocking2, mainly:
- Locking improvements. - Use pool_cache for more items.
-rw-r--r--sys/arch/mips/include/pmap.h4
-rw-r--r--sys/arch/mips/include/vmparam.h6
-rw-r--r--sys/arch/mips/mips/pmap.c12
-rw-r--r--sys/compat/svr4/svr4_misc.c5
-rw-r--r--sys/conf/param.c6
-rw-r--r--sys/kern/init_main.c7
-rw-r--r--sys/kern/kern_descrip.c102
-rw-r--r--sys/kern/kern_exec.c46
-rw-r--r--sys/kern/kern_exit.c7
-rw-r--r--sys/kern/kern_lwp.c13
-rw-r--r--sys/kern/kern_proc.c89
-rw-r--r--sys/kern/kern_resource.c25
-rw-r--r--sys/kern/subr_lockdebug.c7
-rw-r--r--sys/kern/subr_pool.c86
-rw-r--r--sys/kern/sys_pipe.c290
-rw-r--r--sys/kern/tty.c49
-rw-r--r--sys/kern/uipc_syscalls.c8
-rw-r--r--sys/kern/vfs_syscalls.c26
-rw-r--r--sys/miscfs/procfs/procfs_vfsops.c5
-rw-r--r--sys/sys/file.h6
-rw-r--r--sys/sys/lwp.h4
-rw-r--r--sys/sys/pipe.h4
-rw-r--r--sys/sys/pool.h6
-rw-r--r--sys/sys/proc.h8
-rw-r--r--sys/sys/resourcevar.h3
-rw-r--r--usr.bin/sockstat/sockstat.c6
-rw-r--r--usr.bin/vmstat/vmstat.c16
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;