Module Name: src
Committed By: rmind
Date: Sun May 1 01:15:18 UTC 2011
Modified Files:
src/sys/kern: kern_acct.c kern_fork.c kern_proc.c kern_resource.c
src/sys/sys: proc.h resourcevar.h
Log Message:
- Remove FORK_SHARELIMIT and PL_SHAREMOD, simplify lim_privatise().
- Use kmem(9) for struct plimit::pl_corename.
To generate a diff of this commit:
cvs rdiff -u -r1.91 -r1.92 src/sys/kern/kern_acct.c
cvs rdiff -u -r1.182 -r1.183 src/sys/kern/kern_fork.c
cvs rdiff -u -r1.178 -r1.179 src/sys/kern/kern_proc.c
cvs rdiff -u -r1.160 -r1.161 src/sys/kern/kern_resource.c
cvs rdiff -u -r1.305 -r1.306 src/sys/sys/proc.h
cvs rdiff -u -r1.50 -r1.51 src/sys/sys/resourcevar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_acct.c
diff -u src/sys/kern/kern_acct.c:1.91 src/sys/kern/kern_acct.c:1.92
--- src/sys/kern/kern_acct.c:1.91 Sat Mar 26 21:31:23 2011
+++ src/sys/kern/kern_acct.c Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_acct.c,v 1.91 2011/03/26 21:31:23 dholland Exp $ */
+/* $NetBSD: kern_acct.c,v 1.92 2011/05/01 01:15:18 rmind Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_acct.c,v 1.91 2011/03/26 21:31:23 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_acct.c,v 1.92 2011/05/01 01:15:18 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -423,7 +423,7 @@
*
* XXX We should think about the CPU limit, too.
*/
- lim_privatise(p, false);
+ lim_privatise(p);
orlim = p->p_rlimit[RLIMIT_FSIZE];
/* Set current and max to avoid illegal values */
p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
Index: src/sys/kern/kern_fork.c
diff -u src/sys/kern/kern_fork.c:1.182 src/sys/kern/kern_fork.c:1.183
--- src/sys/kern/kern_fork.c:1.182 Tue Apr 26 16:36:42 2011
+++ src/sys/kern/kern_fork.c Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_fork.c,v 1.182 2011/04/26 16:36:42 joerg Exp $ */
+/* $NetBSD: kern_fork.c,v 1.183 2011/05/01 01:15:18 rmind Exp $ */
/*-
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.182 2011/04/26 16:36:42 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.183 2011/05/01 01:15:18 rmind Exp $");
#include "opt_ktrace.h"
@@ -358,20 +358,15 @@
p2->p_cwdi = cwdinit();
/*
- * p_limit (rlimit stuff) is usually copy-on-write, so we just need
- * to bump pl_refcnt.
- * However in some cases like clone the parent and child
- * share limits - in which case nothing else must have a copy
- * of the limits (PL_SHAREMOD is set).
+ * Note: p_limit (rlimit stuff) is copy-on-write, so normally
+ * we just need increase pl_refcnt.
*/
- if (__predict_false(flags & FORK_SHARELIMIT))
- lim_privatise(p1, 1);
p1_lim = p1->p_limit;
- if (p1_lim->pl_flags & PL_WRITEABLE && !(flags & FORK_SHARELIMIT))
- p2->p_limit = lim_copy(p1_lim);
- else {
+ if (!p1_lim->pl_writeable) {
lim_addref(p1_lim);
p2->p_limit = p1_lim;
+ } else {
+ p2->p_limit = lim_copy(p1_lim);
}
p2->p_lflag = ((flags & FORK_PPWAIT) ? PL_PPWAIT : 0);
Index: src/sys/kern/kern_proc.c
diff -u src/sys/kern/kern_proc.c:1.178 src/sys/kern/kern_proc.c:1.179
--- src/sys/kern/kern_proc.c:1.178 Sun May 1 00:22:36 2011
+++ src/sys/kern/kern_proc.c Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_proc.c,v 1.178 2011/05/01 00:22:36 rmind Exp $ */
+/* $NetBSD: kern_proc.c,v 1.179 2011/05/01 01:15:18 rmind Exp $ */
/*-
* Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.178 2011/05/01 00:22:36 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.179 2011/05/01 01:15:18 rmind Exp $");
#ifdef _KERNEL_OPT
#include "opt_kstack.h"
@@ -453,8 +453,11 @@
rlim[RLIMIT_MEMLOCK].rlim_max = lim;
rlim[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
+ /* Note that default core name has zero length. */
limit0.pl_corename = defcorename;
+ limit0.pl_cnlen = 0;
limit0.pl_refcnt = 1;
+ limit0.pl_writeable = false;
limit0.pl_sv_limit = NULL;
/* Configure virtual memory system, set vm rlimits. */
Index: src/sys/kern/kern_resource.c
diff -u src/sys/kern/kern_resource.c:1.160 src/sys/kern/kern_resource.c:1.161
--- src/sys/kern/kern_resource.c:1.160 Sun May 1 00:22:36 2011
+++ src/sys/kern/kern_resource.c Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_resource.c,v 1.160 2011/05/01 00:22:36 rmind Exp $ */
+/* $NetBSD: kern_resource.c,v 1.161 2011/05/01 01:15:18 rmind Exp $ */
/*-
* Copyright (c) 1982, 1986, 1991, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.160 2011/05/01 00:22:36 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.161 2011/05/01 01:15:18 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -355,7 +355,7 @@
if (error)
return (error);
- lim_privatise(p, false);
+ lim_privatise(p);
/* p->p_limit is now unchangeable */
alimp = &p->p_rlimit[which];
@@ -598,12 +598,9 @@
}
/*
- * Make a copy of the plimit structure.
- * We share these structures copy-on-write after fork,
- * and copy when a limit is changed.
+ * lim_copy: make a copy of the plimit structure.
*
- * Unfortunately (due to PL_SHAREMOD) it is possibly for the structure
- * we are copying to change beneath our feet!
+ * We use copy-on-write after fork, and copy when a limit is changed.
*/
struct plimit *
lim_copy(struct plimit *lim)
@@ -614,7 +611,7 @@
newlim = pool_cache_get(plimit_cache, PR_WAITOK);
mutex_init(&newlim->pl_lock, MUTEX_DEFAULT, IPL_NONE);
- newlim->pl_flags = 0;
+ newlim->pl_writeable = false;
newlim->pl_refcnt = 1;
newlim->pl_sv_limit = NULL;
@@ -622,30 +619,38 @@
memcpy(newlim->pl_rlimit, lim->pl_rlimit,
sizeof(struct rlimit) * RLIM_NLIMITS);
+ /*
+ * Note: the common case is a use of default core name.
+ */
alen = 0;
corename = NULL;
for (;;) {
if (lim->pl_corename == defcorename) {
newlim->pl_corename = defcorename;
+ newlim->pl_cnlen = 0;
break;
}
- len = strlen(lim->pl_corename) + 1;
- if (len <= alen) {
+ len = lim->pl_cnlen;
+ if (len == alen) {
newlim->pl_corename = corename;
+ newlim->pl_cnlen = len;
memcpy(corename, lim->pl_corename, len);
corename = NULL;
break;
}
mutex_exit(&lim->pl_lock);
- if (corename != NULL)
- free(corename, M_TEMP);
+ if (corename) {
+ kmem_free(corename, alen);
+ }
alen = len;
- corename = malloc(alen, M_TEMP, M_WAITOK);
+ corename = kmem_alloc(alen, KM_SLEEP);
mutex_enter(&lim->pl_lock);
}
mutex_exit(&lim->pl_lock);
- if (corename != NULL)
- free(corename, M_TEMP);
+
+ if (corename) {
+ kmem_free(corename, alen);
+ }
return newlim;
}
@@ -656,44 +661,33 @@
}
/*
- * Give a process it's own private plimit structure.
- * This will only be shared (in fork) if modifications are to be shared.
+ * lim_privatise: give a process its own private plimit structure.
*/
void
-lim_privatise(struct proc *p, bool set_shared)
+lim_privatise(proc_t *p)
{
- struct plimit *lim, *newlim;
+ struct plimit *lim = p->p_limit, *newlim;
- lim = p->p_limit;
- if (lim->pl_flags & PL_WRITEABLE) {
- if (set_shared)
- lim->pl_flags |= PL_SHAREMOD;
+ if (lim->pl_writeable) {
return;
}
- if (set_shared && lim->pl_flags & PL_SHAREMOD)
- return;
-
newlim = lim_copy(lim);
mutex_enter(p->p_lock);
- if (p->p_limit->pl_flags & PL_WRITEABLE) {
- /* Someone crept in while we were busy */
+ if (p->p_limit->pl_writeable) {
+ /* Other thread won the race. */
mutex_exit(p->p_lock);
lim_free(newlim);
- if (set_shared)
- p->p_limit->pl_flags |= PL_SHAREMOD;
return;
}
/*
- * Since most accesses to p->p_limit aren't locked, we must not
- * delete the old limit structure yet.
+ * Since p->p_limit can be accessed without locked held,
+ * old limit structure must not be deleted yet.
*/
newlim->pl_sv_limit = p->p_limit;
- newlim->pl_flags |= PL_WRITEABLE;
- if (set_shared)
- newlim->pl_flags |= PL_SHAREMOD;
+ newlim->pl_writeable = true;
p->p_limit = newlim;
mutex_exit(p->p_lock);
}
@@ -703,17 +697,20 @@
{
struct plimit *lim;
char *oname;
+ size_t olen;
- lim_privatise(p, false);
+ lim_privatise(p);
lim = p->p_limit;
mutex_enter(&lim->pl_lock);
oname = lim->pl_corename;
+ olen = lim->pl_cnlen;
lim->pl_corename = name;
+ lim->pl_cnlen = len;
mutex_exit(&lim->pl_lock);
if (oname != defcorename) {
- free(oname, M_TEMP);
+ kmem_free(oname, olen);
}
}
@@ -727,7 +724,7 @@
return;
}
if (lim->pl_corename != defcorename) {
- free(lim->pl_corename, M_TEMP);
+ kmem_free(lim->pl_corename, lim->pl_cnlen);
}
sv_lim = lim->pl_sv_limit;
mutex_destroy(&lim->pl_lock);
@@ -871,7 +868,7 @@
}
/* Allocate, copy and set the new core name for plimit structure. */
- cname = malloc(++len, M_TEMP, M_WAITOK | M_CANFAIL);
+ cname = kmem_alloc(++len, KM_NOSLEEP);
if (cname == NULL) {
error = ENOMEM;
goto done;
Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.305 src/sys/sys/proc.h:1.306
--- src/sys/sys/proc.h:1.305 Wed Apr 27 00:36:48 2011
+++ src/sys/sys/proc.h Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.305 2011/04/27 00:36:48 rmind Exp $ */
+/* $NetBSD: proc.h,v 1.306 2011/05/01 01:15:18 rmind Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -432,7 +432,6 @@
#define FORK_NOWAIT 0x0020 /* Make init the parent of the child */
#define FORK_CLEANFILES 0x0040 /* Start with a clean descriptor set */
#define FORK_SYSTEM 0x0080 /* Fork a kernel thread */
-#define FORK_SHARELIMIT 0x0100 /* Share rlimit values */
extern struct proc proc0; /* Process slot for swapper */
extern u_int nprocs; /* Current number of procs */
Index: src/sys/sys/resourcevar.h
diff -u src/sys/sys/resourcevar.h:1.50 src/sys/sys/resourcevar.h:1.51
--- src/sys/sys/resourcevar.h:1.50 Sun May 1 00:22:36 2011
+++ src/sys/sys/resourcevar.h Sun May 1 01:15:18 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: resourcevar.h,v 1.50 2011/05/01 00:22:36 rmind Exp $ */
+/* $NetBSD: resourcevar.h,v 1.51 2011/05/01 01:15:18 rmind Exp $ */
/*
* Copyright (c) 1991, 1993
@@ -63,25 +63,20 @@
#ifdef _KERNEL
/*
- * Kernel shareable process resource limits. Because this structure
- * is moderately large but changes infrequently, it is normally
- * shared copy-on-write after forks. If a group of processes
- * ("threads") share modifications, the PL_SHAREMOD flag is set,
- * and a copy must be made for the child of a new fork that isn't
- * sharing modifications to the limits.
+ * Process resource limits. Since this structure is moderately large,
+ * but changes infrequently, it is shared copy-on-write after forks.
*
- * The PL_xxx flags are never cleared, once either is set p->p_limit
- * will never be changed again.
+ * When a separate copy is created, then 'pl_writeable' is set to true,
+ * and 'pl_sv_limit' is pointed to the old proc_t::p_limit structure.
*/
struct plimit {
struct rlimit pl_rlimit[RLIM_NLIMITS];
char * pl_corename;
-#define PL_SHAREMOD 0x01 /* modifications are shared */
-#define PL_WRITEABLE 0x02 /* private to this process */
- int pl_flags;
- int pl_refcnt; /* number of references */
- kmutex_t pl_lock; /* mutex for pl_refcnt */
- struct plimit * pl_sv_limit; /* saved when PL_WRITEABLE set */
+ size_t pl_cnlen;
+ u_int pl_refcnt;
+ bool pl_writeable;
+ kmutex_t pl_lock;
+ struct plimit * pl_sv_limit;
};
/* add user profiling from AST XXXSMP */
@@ -107,9 +102,9 @@
void calcru(struct proc *, struct timeval *, struct timeval *,
struct timeval *, struct timeval *);
-struct plimit *lim_copy(struct plimit *lim);
-void lim_addref(struct plimit *lim);
-void lim_privatise(struct proc *p, bool set_shared);
+struct plimit *lim_copy(struct plimit *);
+void lim_addref(struct plimit *);
+void lim_privatise(struct proc *);
void lim_setcorename(struct proc *, char *, size_t);
void lim_free(struct plimit *);