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