FreeBSD/sys/kern/vfs_bio.c
/*
 * Calculating buffer cache scaling values and reserve space for buffer
 * headers.  This is called during low level kernel initialization and
 * may be called more then once.  We CANNOT write to the memory area
 * being reserved at this time.
 */
Calculating buffer cache scaling values and reserve space for buffer
headers.  This is called during low level kernel initialization and
may be called more then once.  We CANNOT write to the memory area
being reserved at this time.
Calculating buffer cache scaling values and reserve space for buffer headers . This is called during low level kernel initialization and may be called more then once . We CANNOT write to the memory area being reserved at this time .
caddr_t
kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est)
{
	int tuned_nbuf;
	long maxbuf, maxbuf_sz, buf_sz,	biotmap_sz;
	physmem_est = physmem_est * (PAGE_SIZE / 1024);
	if (nbuf == 0) {
		int factor = 4 * BKVASIZE / 1024;
		nbuf = 50;
		if (physmem_est > 4096)
			nbuf += min((physmem_est - 4096) / factor,
			    65536 / factor);
		if (physmem_est > 65536)
			nbuf += min((physmem_est - 65536) * 2 / (factor * 5),
			    32 * 1024 * 1024 / (factor * 5));
		if (maxbcache && nbuf > maxbcache / BKVASIZE)
			nbuf = maxbcache / BKVASIZE;
		tuned_nbuf = 1;
	} else
		tuned_nbuf = 0;
	maxbuf = (LONG_MAX / 3) / BKVASIZE;
	if (nbuf > maxbuf) {
		if (!tuned_nbuf)
			printf("Warning: nbufs lowered from %d to %ld\n", nbuf,
			    maxbuf);
		nbuf = maxbuf;
	}
	if (bio_transient_maxcnt == 0 && unmapped_buf_allowed) {
		maxbuf_sz = maxbcache != 0 ? maxbcache : maxbuf * BKVASIZE;
		buf_sz = (long)nbuf * BKVASIZE;
		if (buf_sz < maxbuf_sz / TRANSIENT_DENOM *
		    (TRANSIENT_DENOM - 1)) {
			biotmap_sz = maxbuf_sz - buf_sz;
		} else {
			biotmap_sz = buf_sz / TRANSIENT_DENOM;
			buf_sz -= biotmap_sz;
		}
		if (biotmap_sz / INT_MAX > MAXPHYS)
			bio_transient_maxcnt = INT_MAX;
		else
			bio_transient_maxcnt = biotmap_sz / MAXPHYS;
		if (bio_transient_maxcnt > 1024)
			bio_transient_maxcnt = 1024;
		if (tuned_nbuf)
			nbuf = buf_sz / BKVASIZE;
	}
	nswbuf = min(nbuf / 4, 256);
	TUNABLE_INT_FETCH("kern.nswbuf", &nswbuf);
	if (nswbuf < NSWBUF_MIN)
		nswbuf = NSWBUF_MIN;
	swbuf = (void *)v;
	v = (caddr_t)(swbuf + nswbuf);
	buf = (void *)v;
	v = (caddr_t)(buf + nbuf);
	return(v);
}
caddr_t kern_vfs_bio_buffer_alloc ( caddr_t v , long physmem_est ) { int tuned_nbuf ; long maxbuf , maxbuf_sz , buf_sz , biotmap_sz ; physmem_est = physmem_est * ( PAGE_SIZE / 1024 ) ; if ( nbuf == 0 ) { int factor = 4 * BKVASIZE / 1024 ; nbuf = 50 ; if ( physmem_est > 4096 ) nbuf += min ( ( physmem_est - 4096 ) / factor , 65536 / factor ) ; if ( physmem_est > 65536 ) nbuf += min ( ( physmem_est - 65536 ) * 2 / ( factor * 5 ) , 32 * 1024 * 1024 / ( factor * 5 ) ) ; if ( maxbcache && nbuf > maxbcache / BKVASIZE ) nbuf = maxbcache / BKVASIZE ; tuned_nbuf = 1 ; } else tuned_nbuf = 0 ; maxbuf = ( LONG_MAX / 3 ) / BKVASIZE ; if ( nbuf > maxbuf ) { if ( ! tuned_nbuf ) printf ( " \n " , nbuf , maxbuf ) ; nbuf = maxbuf ; } if ( bio_transient_maxcnt == 0 && unmapped_buf_allowed ) { maxbuf_sz = maxbcache != 0 ? maxbcache : maxbuf * BKVASIZE ; buf_sz = ( long ) nbuf * BKVASIZE ; if ( buf_sz < maxbuf_sz / TRANSIENT_DENOM * ( TRANSIENT_DENOM - 1 ) ) { biotmap_sz = maxbuf_sz - buf_sz ; } else { biotmap_sz = buf_sz / TRANSIENT_DENOM ; buf_sz -= biotmap_sz ; } if ( biotmap_sz / INT_MAX > MAXPHYS ) bio_transient_maxcnt = INT_MAX ; else bio_transient_maxcnt = biotmap_sz / MAXPHYS ; if ( bio_transient_maxcnt > 1024 ) bio_transient_maxcnt = 1024 ; if ( tuned_nbuf ) nbuf = buf_sz / BKVASIZE ; } nswbuf = min ( nbuf / 4 , 256 ) ; TUNABLE_INT_FETCH ( " " , & nswbuf ) ; if ( nswbuf < NSWBUF_MIN ) nswbuf = NSWBUF_MIN ; swbuf = ( void * ) v ; v = ( caddr_t ) ( swbuf + nswbuf ) ; buf = ( void * ) v ; v = ( caddr_t ) ( buf + nbuf ) ; return ( v ) ; }
Calculating buffer cache scaling values and reserve space for buffer
 headers.
Calculating buffer cache scaling values and reserve space for buffer headers .
/*
	 * physmem_est is in pages.  Convert it to kilobytes (assumes
	 * PAGE_SIZE is >= 1K)
	 */ /*
	 * The nominal buffer size (and minimum KVA allocation) is BKVASIZE.
	 * For the first 64MB of ram nominally allocate sufficient buffers to
	 * cover 1/4 of our ram.  Beyond the first 64MB allocate additional
	 * buffers to cover 1/10 of our ram over 64MB.  When auto-sizing
	 * the buffer cache we limit the eventual kva reservation to
	 * maxbcache bytes.
	 *
	 * factor represents the 1/4 x ram conversion.
	 */ /* XXX Avoid unsigned long overflows later on with maxbufspace. */ /*
	 * Ideal allocation size for the transient bio submap is 10%
	 * of the maximal space buffer map.  This roughly corresponds
	 * to the amount of the buffer mapped for typical UFS load.
	 *
	 * Clip the buffer map to reserve space for the transient
	 * BIOs, if its extent is bigger than 90% (80% on i386) of the
	 * maximum buffer map extent on the platform.
	 *
	 * The fall-back to the maxbuf in case of maxbcache unset,
	 * allows to not trim the buffer KVA for the architectures
	 * with ample KVA space.
	 */ /*
			 * There is more KVA than memory.  Do not
			 * adjust buffer map size, and assign the rest
			 * of maxbuf to transient map.
			 */ /*
			 * Buffer map spans all KVA we could afford on
			 * this platform.  Give 10% (20% on i386) of
			 * the buffer map to the transient bio map.
			 */ /*
		 * Artificially limit to 1024 simultaneous in-flight I/Os
		 * using the transient mapping.
		 */ /*
	 * swbufs are used as temporary holders for I/O, such as paging I/O.
	 * We have no less then 16 and no more then 256.
	 */ /*
	 * Reserve space for the buffer cache buffers
	 */