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 *);
 

Reply via email to