Subject: More pools
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-kern
Date: 10/28/2003 09:24:22
Folks,

The following diff adds pools for credentials, session headers and lockf
structures.  These appear to be the last of the fixed-sized structures
that are malloc'd with any serious frequency (at least for my usage
patterns).

One thing I don't entirely like is the new lf_init() and crinit()
functions that simply initialise the pools.  I wonder if there's a
better way of doing pool initialisation, maybe using link sets (maybe
even limited to pools that use pool_allocator_nointr()?)?  But I
don't want that to hold up this change...  We also have a nice mix of
fooinit() and foo_init() in the kernel, but that's beside the point.

I also wonder if it's worth looking at a pool cache for the cred
pool?  A new cred structure is zero'd then one element set to '1'.  Any
thoughts on this one?  I'm not sure where that trade off is in terms of
function call overhead, etc but I suspect this is too simple a case to
use pool caches.

Simon.
--
Simon Burge                                   <simonb@wasabisystems.com>
NetBSD Development, Support and Service:   http://www.wasabisystems.com/


Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.224
diff -d -p -u -r1.224 init_main.c
--- kern/init_main.c	7 Aug 2003 16:31:41 -0000	1.224
+++ kern/init_main.c	27 Oct 2003 21:37:58 -0000
@@ -109,6 +109,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,
 #include <sys/disk.h>
 #include <sys/exec.h>
 #include <sys/socketvar.h>
+#include <sys/lockf.h>
 #include <sys/protosw.h>
 #include <sys/reboot.h>
 #include <sys/user.h>
@@ -287,11 +288,12 @@ main(void)
 	/* Initialize the sysctl subsystem. */
 	sysctl_init();
 
-	/*
-	 * Initialize process and pgrp structures.
-	 */
+	/* Initialize process and pgrp structures. */
 	procinit();
 
+	/* Initialize file locking. */
+	lf_init();
+
 #ifdef LKM
 	/* Initialize the LKM system. */
 	lkm_init();
@@ -323,7 +325,8 @@ main(void)
 
 	callout_init(&l->l_tsleep_ch);
 
-	/* Create credentials. */
+	/* Initialize and create credentials. */
+	crinit();
 	cred0.p_refcnt = 1;
 	p->p_cred = &cred0;
 	p->p_ucred = crget();
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.66
diff -d -p -u -r1.66 kern_proc.c
--- kern/kern_proc.c	16 Sep 2003 12:05:49 -0000	1.66
+++ kern/kern_proc.c	27 Oct 2003 21:37:58 -0000
@@ -191,10 +191,10 @@ struct pool ras_pool;
 struct pool sadata_pool;
 struct pool saupcall_pool;
 struct pool ptimer_pool;
+struct pool session_pool;
 
 MALLOC_DEFINE(M_EMULDATA, "emuldata", "Per-process emulation data");
 MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
-MALLOC_DEFINE(M_SESSION, "session", "session header");
 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
 
 /*
@@ -279,6 +279,8 @@ procinit(void)
 	    &pool_allocator_nointr);
 	pool_init(&ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl",
 	    &pool_allocator_nointr);
+	pool_init(&session_pool, sizeof(struct session), 0, 0, 0, "sessionpl",
+	    &pool_allocator_nointr);
 }
 
 /*
@@ -685,8 +687,7 @@ enterpgrp(struct proc *p, pid_t pgid, in
 		new_pgrp = NULL;
 	}
 	if (mksess)
-		MALLOC(sess, struct session *, sizeof(struct session),
-			    M_SESSION, M_WAITOK);
+		sess = pool_get(&session_pool, M_WAITOK);
 	else
 		sess = NULL;
 
@@ -803,7 +804,7 @@ enterpgrp(struct proc *p, pid_t pgid, in
     done:
 	proclist_unlock_write(s);
 	if (sess != NULL)
-		free(sess, M_SESSION);
+		pool_put(&session_pool, sess);
 	if (new_pgrp != NULL)
 		pool_put(&pgrp_pool, new_pgrp);
 	if (pg_id != NO_PGID)
@@ -925,7 +926,7 @@ sessdelete(struct session *ss)
 
 	pg_free(ss->s_sid);
 
-	FREE(ss, M_SESSION);
+	pool_put(&session_pool, ss);
 }
 
 /*
Index: kern/kern_prot.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_prot.c,v
retrieving revision 1.80
diff -d -p -u -r1.80 kern_prot.c
--- kern/kern_prot.c	7 Aug 2003 16:31:47 -0000	1.80
+++ kern/kern_prot.c	27 Oct 2003 21:37:58 -0000
@@ -52,14 +52,14 @@ __KERNEL_RCSID(0, "$NetBSD: kern_prot.c,
 #include <sys/proc.h>
 #include <sys/timeb.h>
 #include <sys/times.h>
-#include <sys/malloc.h>
+#include <sys/pool.h>
 #include <sys/syslog.h>
 
 #include <sys/mount.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
-MALLOC_DEFINE(M_CRED, "cred", "credentials");
+struct pool cred_pool;
 
 int	sys_getpid(struct lwp *, void *, register_t *);
 int	sys_getpid_with_ppid(struct lwp *, void *, register_t *);
@@ -608,6 +608,14 @@ suser(const struct ucred *cred, u_short 
 	return (EPERM);
 }
 
+void
+crinit(void)
+{
+
+	pool_init(&cred_pool, sizeof(struct ucred), 0, 0, 0,
+	    "credpl", &pool_allocator_nointr);
+}
+
 /*
  * Allocate a zeroed cred structure.
  */
@@ -616,8 +624,8 @@ crget(void)
 {
 	struct ucred *cr;
 
-	MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
-	memset((caddr_t)cr, 0, sizeof(*cr));
+	cr = pool_get(&cred_pool, PR_WAITOK);
+	memset(cr, 0, sizeof(*cr));
 	cr->cr_ref = 1;
 	return (cr);
 }
@@ -631,7 +639,7 @@ crfree(struct ucred *cr)
 {
 
 	if (--cr->cr_ref == 0)
-		FREE((caddr_t)cr, M_CRED);
+		pool_put(&cred_pool, cr);
 }
 
 /*
Index: kern/vfs_lockf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_lockf.c,v
retrieving revision 1.34
diff -d -p -u -r1.34 vfs_lockf.c
--- kern/vfs_lockf.c	25 Oct 2003 09:13:41 -0000	1.34
+++ kern/vfs_lockf.c	27 Oct 2003 21:37:59 -0000
@@ -43,11 +43,11 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,
 #include <sys/file.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
-#include <sys/malloc.h>
+#include <sys/pool.h>
 #include <sys/fcntl.h>
 #include <sys/lockf.h>
 
-MALLOC_DEFINE(M_LOCKF, "lockf", "Byte-range locking structures");
+struct pool lockfpool;
 
 /*
  * This variable controls the maximum number of processes that will
@@ -86,6 +86,14 @@ static void lf_printlist(char *, struct 
  * Use pools for lock allocation.
  */
 
+void
+lf_init(void)
+{
+
+	pool_init(&lockfpool, sizeof(struct lockf), 0, 0, 0,
+	    "lockfpl", &pool_allocator_nointr);
+}
+
 /*
  * If there's a lot of lock contention on a single vnode, locking
  * schemes which allow for more paralleism would be needed.  Given how
@@ -143,8 +151,7 @@ lf_advlock(struct vop_advlock_args *ap, 
 			/*
 			 * byte-range lock might need one more lock.
 			 */
-			MALLOC(sparelock, struct lockf *, sizeof(*lock),
-			    M_LOCKF, M_WAITOK);
+			sparelock = pool_get(&lockfpool, PR_WAITOK);
 			if (sparelock == NULL) {
 				error = ENOMEM;
 				goto quit;
@@ -161,7 +168,7 @@ lf_advlock(struct vop_advlock_args *ap, 
 		return EINVAL;
 	}
 
-	MALLOC(lock, struct lockf *, sizeof(*lock), M_LOCKF, M_WAITOK);
+	lock = pool_get(&lockfpool, PR_WAITOK);
 	if (lock == NULL) {
 		error = ENOMEM;
 		goto quit;
@@ -233,9 +240,9 @@ quit_unlock:
 	simple_unlock(interlock);
 quit:
 	if (lock)
-		FREE(lock, M_LOCKF);
+		pool_put(&lockfpool, lock);
 	if (sparelock)
-		FREE(sparelock, M_LOCKF);
+		pool_put(&lockfpool, sparelock);
 
 	return error;
 }
@@ -273,7 +280,7 @@ lf_setlock(struct lockf *lock, struct lo
 		 * Free the structure and return if nonblocking.
 		 */
 		if ((lock->lf_flags & F_WAIT) == 0) {
-			FREE(lock, M_LOCKF);
+			pool_put(&lockfpool, lock);
 			return EAGAIN;
 		}
 		/*
@@ -306,7 +313,7 @@ lf_setlock(struct lockf *lock, struct lo
 					break;
 				wlwp = waitblock->lf_lwp;
 				if (wlwp == lock->lf_lwp) {
-					free(lock, M_LOCKF);
+					pool_put(&lockfpool, lock);
 					return EDEADLK;
 				}
 			}
@@ -316,7 +323,7 @@ lf_setlock(struct lockf *lock, struct lo
 			 * a cycle to be safe.
 			 */
 			if (i >= maxlockdepth) {
-				free(lock, M_LOCKF);
+				pool_put(&lockfpool, lock);
 				return EDEADLK;
 			}
 		}
@@ -358,7 +365,7 @@ lf_setlock(struct lockf *lock, struct lo
 			lock->lf_next = NOLOCKF;
 		}
 		if (error) {
-			free(lock, M_LOCKF);
+			pool_put(&lockfpool, lock);
 			return error;
 		}
 	}
@@ -404,7 +411,7 @@ lf_setlock(struct lockf *lock, struct lo
 			    overlap->lf_type == F_WRLCK)
 				lf_wakelock(overlap);
 			overlap->lf_type = lock->lf_type;
-			FREE(lock, M_LOCKF);
+			pool_put(&lockfpool, lock);
 			lock = overlap; /* for debug output below */
 			break;
 
@@ -413,7 +420,7 @@ lf_setlock(struct lockf *lock, struct lo
 			 * Check for common starting point and different types.
 			 */
 			if (overlap->lf_type == lock->lf_type) {
-				free(lock, M_LOCKF);
+				pool_put(&lockfpool, lock);
 				lock = overlap; /* for debug output below */
 				break;
 			}
@@ -454,7 +461,7 @@ lf_setlock(struct lockf *lock, struct lo
 				needtolink = 0;
 			} else
 				*prev = overlap->lf_next;
-			free(overlap, M_LOCKF);
+			pool_put(&lockfpool, overlap);
 			continue;
 
 		case 4: /* overlap starts before lock */
@@ -526,7 +533,7 @@ lf_clearlock(struct lockf *unlock, struc
 
 		case 1: /* overlap == lock */
 			*prev = overlap->lf_next;
-			FREE(overlap, M_LOCKF);
+			pool_put(&lockfpool, overlap);
 			break;
 
 		case 2: /* overlap contains lock: split it */
@@ -541,7 +548,7 @@ lf_clearlock(struct lockf *unlock, struc
 		case 3: /* lock contains overlap */
 			*prev = overlap->lf_next;
 			lf = overlap->lf_next;
-			free(overlap, M_LOCKF);
+			pool_put(&lockfpool, overlap);
 			continue;
 
 		case 4: /* overlap starts before lock */
Index: sys/lockf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lockf.h,v
retrieving revision 1.14
diff -d -p -u -r1.14 lockf.h
--- sys/lockf.h	7 Aug 2003 16:34:07 -0000	1.14
+++ sys/lockf.h	27 Oct 2003 21:38:02 -0000
@@ -71,6 +71,7 @@ struct lockf {
 #ifdef _KERNEL
 
 int lf_advlock(struct vop_advlock_args *, struct lockf **, off_t);
+void lf_init(void);
 
 #endif /* _KERNEL */
 
Index: sys/ucred.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ucred.h,v
retrieving revision 1.18
diff -d -p -u -r1.18 ucred.h
--- sys/ucred.h	7 Aug 2003 16:34:21 -0000	1.18
+++ sys/ucred.h	27 Oct 2003 21:38:02 -0000
@@ -75,6 +75,7 @@ struct ucred {
 int		do_setresuid(struct lwp *, uid_t, uid_t, uid_t, u_int);
 int		do_setresgid(struct lwp *, gid_t, gid_t, gid_t, u_int);
 
+void		crinit(void);
 struct ucred	*crcopy(struct ucred *);
 struct ucred	*crdup(const struct ucred *);
 void		crfree(struct ucred *);