Subject: Re: vnode: table is full
To: David Brownlee <abs@netbsd.org>
From: Jaromír Doleček <dolecek@ibis.cz>
List: current-users
Date: 07/03/2000 21:51:04
David Brownlee wrote:
> 	Sounds like it would be even better to determine them at boot
> 	time...

Hmm, what about following patch ? It
1. adds some hints to the warning about table full conditions (vnode, file
	and proc tables ATM, is tablefull() used anywhere else ?)
2. if NVNODE was not specified explicitly in kernel config, the code adjusts
	the initial maximum number of vnodes in namei cache on boot, so that
	they take roughly 0.5% of system memory, or NVNODE vnodes if it's
	greater; this means like 1600 vnodes for i386 with 64MB RAM
	maybe this is too conservative *shrug* 


Index: sys/systm.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/systm.h,v
retrieving revision 1.111
diff -u -r1.111 systm.h
--- systm.h	2000/06/10 18:44:45	1.111
+++ systm.h	2000/07/03 19:41:59
@@ -199,7 +199,7 @@
 int	humanize_number __P((char *, size_t, u_int64_t, const char *, int));
 int	format_bytes __P((char *, size_t, u_int64_t));
 
-void	tablefull __P((const char *));
+void	tablefull __P((const char *, const char *));
 
 int	kcopy __P((const void *, void *, size_t));
 
Index: sys/param.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/param.h,v
retrieving revision 1.101
diff -u -r1.101 param.h
--- param.h	2000/06/30 07:44:06	1.101
+++ param.h	2000/07/03 19:42:08
@@ -131,6 +131,7 @@
 #endif
 #ifndef NVNODE
 #define	NVNODE (NPROC + NTEXT + 100)
+#define NVNODE_IMPLICIT
 #endif
 #endif /* _KERNEL */
 
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_fork.c,v
retrieving revision 1.68
diff -u -r1.68 kern_fork.c
--- kern_fork.c	2000/06/27 17:41:20	1.68
+++ kern_fork.c	2000/07/03 19:42:09
@@ -139,7 +139,7 @@
 	uid = p1->p_cred->p_ruid;
 	if (__predict_false((nprocs >= maxproc - 1 && uid != 0) ||
 			    nprocs >= maxproc)) {
-		tablefull("proc");
+		tablefull("proc", "increase kern.maxproc or NPROC");
 		return (EAGAIN);
 	}
 
Index: kern/kern_descrip.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_descrip.c,v
retrieving revision 1.68
diff -u -r1.68 kern_descrip.c
--- kern_descrip.c	2000/06/27 17:41:16	1.68
+++ kern_descrip.c	2000/07/03 19:42:19
@@ -691,7 +691,7 @@
 	if ((error = fdalloc(p, 0, &i)) != 0)
 		return (error);
 	if (nfiles >= maxfiles) {
-		tablefull("file");
+		tablefull("file", "increase kern.maxfiles or MAXFILES");
 		return (ENFILE);
 	}
 	/*
Index: kern/subr_prf.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/subr_prf.c,v
retrieving revision 1.74
diff -u -r1.74 subr_prf.c
--- subr_prf.c	2000/06/10 18:44:44	1.74
+++ subr_prf.c	2000/07/03 19:42:30
@@ -167,10 +167,13 @@
  */
 
 void
-tablefull(tab)
-	const char *tab;
+tablefull(tab, extra)
+	const char *tab, *extra;
 {
-	log(LOG_ERR, "%s: table is full\n", tab);
+	if (extra)
+		log(LOG_ERR, "%s: table is full - %s\n", tab, extra);
+	else
+		log(LOG_ERR, "%s: table is full\n", tab);
 }
 
 /*
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/vfs_subr.c,v
retrieving revision 1.131
diff -u -r1.131 vfs_subr.c
--- vfs_subr.c	2000/06/27 23:52:18	1.131
+++ vfs_subr.c	2000/07/03 19:43:04
@@ -490,7 +490,7 @@
 			simple_unlock(&vnode_free_list_slock);
 			if (mp && error != EDEADLK)
 				vfs_unbusy(mp);
-			tablefull("vnode");
+			tablefull("vnode", "increase kern.maxvnodes or NVNODE");
 			*vpp = 0;
 			return (ENFILE);
 		}
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/init_main.c,v
retrieving revision 1.174
diff -u -r1.174 init_main.c
--- init_main.c	2000/06/27 17:41:12	1.174
+++ init_main.c	2000/07/03 19:43:10
@@ -188,6 +188,9 @@
 #if defined(NFSSERVER) || defined(NFS)
 	extern void nfs_init __P((void));
 #endif
+#ifdef NVNODE_IMPLICIT
+	int usevnodes;
+#endif
 
 	/*
 	 * Initialize the current process pointer (curproc) before
@@ -496,6 +499,17 @@
 	 */
 	start_init_exec = 1;
 	wakeup((void *)&start_init_exec);
+
+#ifdef NVNODE_IMPLICIT
+	/*
+	 * If maximum number of vnodes in namei vnode cache is not explicitly
+	 * defined in kernel config, adjust the number such as we use roughly
+	 * 0.5% of memory for vnode cache (but not less than NVNODE vnodes).
+	 */
+	usevnodes = (ptoa(physmem) / 200) / sizeof(struct vnode);
+	if (usevnodes > desiredvnodes) 
+		desiredvnodes = usevnodes;
+#endif
 
 	/* The scheduler is an infinite loop. */
 	uvm_scheduler();
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
@@@@  Wanna a real operating system ? Go and get NetBSD, damn!  @@@@