svn commit: r189595 - in head/sys: kern sys ufs/ffs vm

John Baldwin jhb at FreeBSD.org
Mon Mar 9 12:35:22 PDT 2009


Author: jhb
Date: Mon Mar  9 19:35:20 2009
New Revision: 189595
URL: http://svn.freebsd.org/changeset/base/189595

Log:
  Adjust some variables (mostly related to the buffer cache) that hold
  address space sizes to be longs instead of ints.  Specifically, the follow
  values are now longs: runningbufspace, bufspace, maxbufspace,
  bufmallocspace, maxbufmallocspace, lobufspace, hibufspace, lorunningspace,
  hirunningspace, maxswzone, maxbcache, and maxpipekva.  Previously, a
  relatively small number (~ 44000) of buffers set in kern.nbuf would result
  in integer overflows resulting either in hangs or bogus values of
  hidirtybuffers and lodirtybuffers.  Now one has to overflow a long to see
  such problems.  There was a check for a nbuf setting that would cause
  overflows in the auto-tuning of nbuf.  I've changed it to always check and
  cap nbuf but warn if a user-supplied tunable would cause overflow.
  
  Note that this changes the ABI of several sysctls that are used by things
  like top(1), etc., so any MFC would probably require a some gross shims
  to allow for that.
  
  MFC after:	1 month

Modified:
  head/sys/kern/subr_param.c
  head/sys/kern/sys_pipe.c
  head/sys/kern/vfs_bio.c
  head/sys/sys/buf.h
  head/sys/sys/pipe.h
  head/sys/ufs/ffs/ffs_snapshot.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/vm/vm_init.c
  head/sys/vm/vnode_pager.c

Modified: head/sys/kern/subr_param.c
==============================================================================
--- head/sys/kern/subr_param.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/kern/subr_param.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -89,9 +89,9 @@ int	maxfilesperproc;		/* per-proc open f
 int	ncallout;			/* maximum # of timer events */
 int	nbuf;
 int	nswbuf;
-int	maxswzone;			/* max swmeta KVA storage */
-int	maxbcache;			/* max buffer cache KVA storage */
-int	maxpipekva;			/* Limit on pipe KVA */
+long	maxswzone;			/* max swmeta KVA storage */
+long	maxbcache;			/* max buffer cache KVA storage */
+u_long	maxpipekva;			/* Limit on pipe KVA */
 int 	vm_guest;			/* Running as virtual machine guest? */
 u_long	maxtsiz;			/* max text size */
 u_long	dfldsiz;			/* initial data size limit */
@@ -203,11 +203,11 @@ init_param1(void)
 #ifdef VM_SWZONE_SIZE_MAX
 	maxswzone = VM_SWZONE_SIZE_MAX;
 #endif
-	TUNABLE_INT_FETCH("kern.maxswzone", &maxswzone);
+	TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
 #ifdef VM_BCACHE_SIZE_MAX
 	maxbcache = VM_BCACHE_SIZE_MAX;
 #endif
-	TUNABLE_INT_FETCH("kern.maxbcache", &maxbcache);
+	TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
 
 	maxtsiz = MAXTSIZ;
 	TUNABLE_ULONG_FETCH("kern.maxtsiz", &maxtsiz);
@@ -282,7 +282,7 @@ init_param3(long kmempages)
 	maxpipekva = (kmempages / 20) * PAGE_SIZE;
 	if (maxpipekva < 512 * 1024)
 		maxpipekva = 512 * 1024;
-	TUNABLE_INT_FETCH("kern.ipc.maxpipekva", &maxpipekva);
+	TUNABLE_ULONG_FETCH("kern.ipc.maxpipekva", &maxpipekva);
 }
 
 /*

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/kern/sys_pipe.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -184,7 +184,7 @@ static int pipeallocfail;
 static int piperesizefail;
 static int piperesizeallowed = 1;
 
-SYSCTL_INT(_kern_ipc, OID_AUTO, maxpipekva, CTLFLAG_RDTUN,
+SYSCTL_ULONG(_kern_ipc, OID_AUTO, maxpipekva, CTLFLAG_RDTUN,
 	   &maxpipekva, 0, "Pipe KVA limit");
 SYSCTL_INT(_kern_ipc, OID_AUTO, pipekva, CTLFLAG_RD,
 	   &amountpipekva, 0, "Pipe KVA usage");

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/kern/vfs_bio.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -112,26 +112,26 @@ static void bremfreel(struct buf *bp);
 int vmiodirenable = TRUE;
 SYSCTL_INT(_vfs, OID_AUTO, vmiodirenable, CTLFLAG_RW, &vmiodirenable, 0,
     "Use the VM system for directory writes");
-int runningbufspace;
-SYSCTL_INT(_vfs, OID_AUTO, runningbufspace, CTLFLAG_RD, &runningbufspace, 0,
+long runningbufspace;
+SYSCTL_LONG(_vfs, OID_AUTO, runningbufspace, CTLFLAG_RD, &runningbufspace, 0,
     "Amount of presently outstanding async buffer io");
-static int bufspace;
-SYSCTL_INT(_vfs, OID_AUTO, bufspace, CTLFLAG_RD, &bufspace, 0,
+static long bufspace;
+SYSCTL_LONG(_vfs, OID_AUTO, bufspace, CTLFLAG_RD, &bufspace, 0,
     "KVA memory used for bufs");
-static int maxbufspace;
-SYSCTL_INT(_vfs, OID_AUTO, maxbufspace, CTLFLAG_RD, &maxbufspace, 0,
+static long maxbufspace;
+SYSCTL_LONG(_vfs, OID_AUTO, maxbufspace, CTLFLAG_RD, &maxbufspace, 0,
     "Maximum allowed value of bufspace (including buf_daemon)");
-static int bufmallocspace;
-SYSCTL_INT(_vfs, OID_AUTO, bufmallocspace, CTLFLAG_RD, &bufmallocspace, 0,
+static long bufmallocspace;
+SYSCTL_LONG(_vfs, OID_AUTO, bufmallocspace, CTLFLAG_RD, &bufmallocspace, 0,
     "Amount of malloced memory for buffers");
-static int maxbufmallocspace;
-SYSCTL_INT(_vfs, OID_AUTO, maxmallocbufspace, CTLFLAG_RW, &maxbufmallocspace, 0,
+static long maxbufmallocspace;
+SYSCTL_LONG(_vfs, OID_AUTO, maxmallocbufspace, CTLFLAG_RW, &maxbufmallocspace, 0,
     "Maximum amount of malloced memory for buffers");
-static int lobufspace;
-SYSCTL_INT(_vfs, OID_AUTO, lobufspace, CTLFLAG_RD, &lobufspace, 0,
+static long lobufspace;
+SYSCTL_LONG(_vfs, OID_AUTO, lobufspace, CTLFLAG_RD, &lobufspace, 0,
     "Minimum amount of buffers we want to have");
-int hibufspace;
-SYSCTL_INT(_vfs, OID_AUTO, hibufspace, CTLFLAG_RD, &hibufspace, 0,
+long hibufspace;
+SYSCTL_LONG(_vfs, OID_AUTO, hibufspace, CTLFLAG_RD, &hibufspace, 0,
     "Maximum allowed value of bufspace (excluding buf_daemon)");
 static int bufreusecnt;
 SYSCTL_INT(_vfs, OID_AUTO, bufreusecnt, CTLFLAG_RW, &bufreusecnt, 0,
@@ -142,11 +142,11 @@ SYSCTL_INT(_vfs, OID_AUTO, buffreekvacnt
 static int bufdefragcnt;
 SYSCTL_INT(_vfs, OID_AUTO, bufdefragcnt, CTLFLAG_RW, &bufdefragcnt, 0,
     "Number of times we have had to repeat buffer allocation to defragment");
-static int lorunningspace;
-SYSCTL_INT(_vfs, OID_AUTO, lorunningspace, CTLFLAG_RW, &lorunningspace, 0,
+static long lorunningspace;
+SYSCTL_LONG(_vfs, OID_AUTO, lorunningspace, CTLFLAG_RW, &lorunningspace, 0,
     "Minimum preferred space used for in-progress I/O");
-static int hirunningspace;
-SYSCTL_INT(_vfs, OID_AUTO, hirunningspace, CTLFLAG_RW, &hirunningspace, 0,
+static long hirunningspace;
+SYSCTL_LONG(_vfs, OID_AUTO, hirunningspace, CTLFLAG_RW, &hirunningspace, 0,
     "Maximum amount of space to use for in-progress I/O");
 int dirtybufferflushes;
 SYSCTL_INT(_vfs, OID_AUTO, dirtybufferflushes, CTLFLAG_RW, &dirtybufferflushes,
@@ -324,7 +324,7 @@ runningbufwakeup(struct buf *bp)
 {
 
 	if (bp->b_runningbufspace) {
-		atomic_subtract_int(&runningbufspace, bp->b_runningbufspace);
+		atomic_subtract_long(&runningbufspace, bp->b_runningbufspace);
 		bp->b_runningbufspace = 0;
 		mtx_lock(&rbreqlock);
 		if (runningbufreq && runningbufspace <= lorunningspace) {
@@ -444,7 +444,8 @@ bd_speedup(void)
 caddr_t
 kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est)
 {
-	int maxbuf;
+	int tuned_nbuf;
+	long maxbuf;
 
 	/*
 	 * physmem_est is in pages.  Convert it to kilobytes (assumes
@@ -474,11 +475,17 @@ kern_vfs_bio_buffer_alloc(caddr_t v, lon
 
 		if (maxbcache && nbuf > maxbcache / BKVASIZE)
 			nbuf = maxbcache / BKVASIZE;
+		tuned_nbuf = 1;
+	} else
+		tuned_nbuf = 0;
 
-		/* XXX Avoid integer overflows later on with maxbufspace. */
-		maxbuf = (INT_MAX / 3) / BKVASIZE;
-		if (nbuf > maxbuf)
-			nbuf = maxbuf;
+	/* XXX Avoid unsigned long overflows later on with maxbufspace. */
+	maxbuf = (LONG_MAX / 3) / BKVASIZE;
+	if (nbuf > maxbuf) {
+		if (!tuned_nbuf)
+			printf("Warning: nbufs lowered from %d to %ld\n", nbuf,
+			    maxbuf);
+		nbuf = maxbuf;
 	}
 
 	/*
@@ -548,8 +555,8 @@ bufinit(void)
 	 * this may result in KVM fragmentation which is not handled optimally
 	 * by the system.
 	 */
-	maxbufspace = nbuf * BKVASIZE;
-	hibufspace = imax(3 * maxbufspace / 4, maxbufspace - MAXBSIZE * 10);
+	maxbufspace = (long)nbuf * BKVASIZE;
+	hibufspace = lmax(3 * maxbufspace / 4, maxbufspace - MAXBSIZE * 10);
 	lobufspace = hibufspace - MAXBSIZE;
 
 	lorunningspace = 512 * 1024;
@@ -577,7 +584,7 @@ bufinit(void)
  * be met.  We try to size hidirtybuffers to 3/4 our buffer space assuming
  * BKVASIZE'd (8K) buffers.
  */
-	while (hidirtybuffers * BKVASIZE > 3 * hibufspace / 4) {
+	while ((long)hidirtybuffers * BKVASIZE > 3 * hibufspace / 4) {
 		hidirtybuffers >>= 1;
 	}
 	lodirtybuffers = hidirtybuffers / 2;
@@ -613,7 +620,7 @@ bfreekva(struct buf *bp)
 
 	if (bp->b_kvasize) {
 		atomic_add_int(&buffreekvacnt, 1);
-		atomic_subtract_int(&bufspace, bp->b_kvasize);
+		atomic_subtract_long(&bufspace, bp->b_kvasize);
 		vm_map_remove(buffer_map, (vm_offset_t) bp->b_kvabase,
 		    (vm_offset_t) bp->b_kvabase + bp->b_kvasize);
 		bp->b_kvasize = 0;
@@ -837,7 +844,7 @@ bufwrite(struct buf *bp)
 	 * Normal bwrites pipeline writes
 	 */
 	bp->b_runningbufspace = bp->b_bufsize;
-	atomic_add_int(&runningbufspace, bp->b_runningbufspace);
+	atomic_add_long(&runningbufspace, bp->b_runningbufspace);
 
 	if (!TD_IS_IDLETHREAD(curthread))
 		curthread->td_ru.ru_oublock++;
@@ -1983,7 +1990,7 @@ restart:
 
 				bp->b_kvabase = (caddr_t) addr;
 				bp->b_kvasize = maxsize;
-				atomic_add_int(&bufspace, bp->b_kvasize);
+				atomic_add_long(&bufspace, bp->b_kvasize);
 				atomic_add_int(&bufreusecnt, 1);
 			}
 			vm_map_unlock(buffer_map);
@@ -2707,7 +2714,7 @@ allocbuf(struct buf *bp, int size)
 				} else {
 					free(bp->b_data, M_BIOBUF);
 					if (bp->b_bufsize) {
-						atomic_subtract_int(
+						atomic_subtract_long(
 						    &bufmallocspace,
 						    bp->b_bufsize);
 						bufspacewakeup();
@@ -2744,7 +2751,7 @@ allocbuf(struct buf *bp, int size)
 				bp->b_bufsize = mbsize;
 				bp->b_bcount = size;
 				bp->b_flags |= B_MALLOC;
-				atomic_add_int(&bufmallocspace, mbsize);
+				atomic_add_long(&bufmallocspace, mbsize);
 				return 1;
 			}
 			origbuf = NULL;
@@ -2758,7 +2765,7 @@ allocbuf(struct buf *bp, int size)
 				origbufsize = bp->b_bufsize;
 				bp->b_data = bp->b_kvabase;
 				if (bp->b_bufsize) {
-					atomic_subtract_int(&bufmallocspace,
+					atomic_subtract_long(&bufmallocspace,
 					    bp->b_bufsize);
 					bufspacewakeup();
 					bp->b_bufsize = 0;

Modified: head/sys/sys/buf.h
==============================================================================
--- head/sys/sys/buf.h	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/sys/buf.h	Mon Mar  9 19:35:20 2009	(r189595)
@@ -446,10 +446,10 @@ buf_countdeps(struct buf *bp, int i)
 
 #ifdef _KERNEL
 extern int	nbuf;			/* The number of buffer headers */
-extern int	maxswzone;		/* Max KVA for swap structures */
-extern int	maxbcache;		/* Max KVA for buffer cache */
-extern int	runningbufspace;
-extern int	hibufspace;
+extern long	maxswzone;		/* Max KVA for swap structures */
+extern long	maxbcache;		/* Max KVA for buffer cache */
+extern long	runningbufspace;
+extern long	hibufspace;
 extern int	dirtybufthresh;
 extern int	bdwriteskip;
 extern int	dirtybufferflushes;

Modified: head/sys/sys/pipe.h
==============================================================================
--- head/sys/sys/pipe.h	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/sys/pipe.h	Mon Mar  9 19:35:20 2009	(r189595)
@@ -56,7 +56,7 @@
 /*
  * See sys_pipe.c for info on what these limits mean. 
  */
-extern int	maxpipekva;
+extern u_long	maxpipekva;
 
 /*
  * Pipe buffer information.

Modified: head/sys/ufs/ffs/ffs_snapshot.c
==============================================================================
--- head/sys/ufs/ffs/ffs_snapshot.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/ufs/ffs/ffs_snapshot.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -2229,7 +2229,7 @@ ffs_copyonwrite(devvp, bp)
 			VI_UNLOCK(devvp);
 			if (saved_runningbufspace != 0) {
 				bp->b_runningbufspace = saved_runningbufspace;
-				atomic_add_int(&runningbufspace,
+				atomic_add_long(&runningbufspace,
 					       bp->b_runningbufspace);
 			}
 			return (0);		/* Snapshot gone */
@@ -2354,7 +2354,7 @@ ffs_copyonwrite(devvp, bp)
 	 */
 	if (saved_runningbufspace != 0) {
 		bp->b_runningbufspace = saved_runningbufspace;
-		atomic_add_int(&runningbufspace, bp->b_runningbufspace);
+		atomic_add_long(&runningbufspace, bp->b_runningbufspace);
 	}
 	return (error);
 }

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/ufs/ffs/ffs_vfsops.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -1915,7 +1915,7 @@ ffs_geom_strategy(struct bufobj *bo, str
 					}
 				}
 				bp->b_runningbufspace = bp->b_bufsize;
-				atomic_add_int(&runningbufspace,
+				atomic_add_long(&runningbufspace,
 					       bp->b_runningbufspace);
 			} else {
 				error = ffs_copyonwrite(vp, bp);

Modified: head/sys/vm/vm_init.c
==============================================================================
--- head/sys/vm/vm_init.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/vm/vm_init.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -186,12 +186,12 @@ again:
 		panic("startup: table size inconsistency");
 
 	clean_map = kmem_suballoc(kernel_map, &kmi->clean_sva, &kmi->clean_eva,
-	    nbuf * BKVASIZE + nswbuf * MAXPHYS, FALSE);
+	    (long)nbuf * BKVASIZE + (long)nswbuf * MAXPHYS, FALSE);
 	buffer_map = kmem_suballoc(clean_map, &kmi->buffer_sva,
-	    &kmi->buffer_eva, nbuf * BKVASIZE, FALSE);
+	    &kmi->buffer_eva, (long)nbuf * BKVASIZE, FALSE);
 	buffer_map->system_map = 1;
 	pager_map = kmem_suballoc(clean_map, &kmi->pager_sva, &kmi->pager_eva,
-	    nswbuf * MAXPHYS, FALSE);
+	    (long)nswbuf * MAXPHYS, FALSE);
 	pager_map->system_map = 1;
 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
 	    exec_map_entries * (ARG_MAX + (PAGE_SIZE * 3)), FALSE);

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Mon Mar  9 19:22:45 2009	(r189594)
+++ head/sys/vm/vnode_pager.c	Mon Mar  9 19:35:20 2009	(r189595)
@@ -525,7 +525,7 @@ vnode_pager_input_smlfs(object, m)
 			bp->b_bcount = bsize;
 			bp->b_bufsize = bsize;
 			bp->b_runningbufspace = bp->b_bufsize;
-			atomic_add_int(&runningbufspace, bp->b_runningbufspace);
+			atomic_add_long(&runningbufspace, bp->b_runningbufspace);
 
 			/* do the input */
 			bp->b_iooffset = dbtob(bp->b_blkno);
@@ -905,7 +905,7 @@ vnode_pager_generic_getpages(vp, m, byte
 	bp->b_bcount = size;
 	bp->b_bufsize = size;
 	bp->b_runningbufspace = bp->b_bufsize;
-	atomic_add_int(&runningbufspace, bp->b_runningbufspace);
+	atomic_add_long(&runningbufspace, bp->b_runningbufspace);
 
 	PCPU_INC(cnt.v_vnodein);
 	PCPU_ADD(cnt.v_vnodepgsin, count);


More information about the svn-src-head mailing list