Limit the amount of KVM reserved for the buffer cache and for swap-meta

information.  The default limits only effect machines with > 1GB of ram
and can be overriden with two new kernel conf variables VM_SWZONE_SIZE_MAX
and VM_BCACHE_SIZE_MAX, or with loader variables kern.maxswzone and
kern.maxbcache.  This has the effect of leaving more KVM available for
sizing NMBCLUSTERS and 'maxusers' and should avoid tripups where a sysad
adds memory to a machine and then sees the kernel panic on boot due to
running out of KVM.

Also change the default swap-meta auto-sizing calculation to allocate half
of what it was previously allocating.  The prior defaults were way too high.
Note that we cannot afford to run out of swap-meta structures so we still
stay somewhat conservative here.
This commit is contained in:
Matthew Dillon 2001-08-20 00:41:12 +00:00
parent a35671c197
commit 2f9e4e8025
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81933
8 changed files with 70 additions and 4 deletions

View File

@ -299,7 +299,9 @@ cpu_startup(dummy)
* 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/20 of our ram over 64MB.
* buffers to cover 1/20 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.
*/
@ -312,6 +314,9 @@ cpu_startup(dummy)
16384 / factor);
if (physmem_est > 16384)
nbuf += (physmem_est - 16384) * 2 / (factor * 5);
if (maxbcache && nbuf > physmem_est / BKVASIZE)
nbuf = maxbcache / BKVASIZE;
}
/*

View File

@ -409,6 +409,33 @@ This overrides completely the value
determined when the kernel was compiled.
Modifies
.Va VM_KMEM_SIZE .
.It Va kern.maxswzone
Limits the amount of KVM to be used to hold swap
meta information, which directly governs the
maximum amount of swap the system can support.
This value is specified in bytes of KVA space
and defaults to around 70MBytes. Care should be taken
to not reduce this value such that the actual
amount of configured swap exceeds 1/2 the
kernel-supported swap. The default 70MB allows
the kernel to support a maximum of (approximately)
14GB of configured swap. Only mess around with
this parameter if you need to greatly extend the
KVM reservation for other resources such as the
buffer cache or NMBCLUSTERS. Modifies
.Va VM_SWZONE_SIZE_MAX
.It Va kern.maxbcache
Limits the amount of KVM reserved for use by the
buffer cache, specified in bytes. The default
maximum is 200MB. This parameter is used to
prevent the buffer cache from eating to much
KVM in large-memory machine configurations.
Only mess around with this parameter if you need to
greatly extend the KVM reservation for other resources
such as the swap zone or NMBCLUSTERS. Note that
the NBUF parameter will override this limit.
Modifies
.Va VM_BCACHE_SIZE_MAX
.It Va machdep.pccard.pcic_irq
Overrides the IRQ normally assigned to a PCCARD controller.
Typically the first available interrupt will be allocated,

View File

@ -173,6 +173,8 @@ MAXFILES opt_param.h
NBUF opt_param.h
NMBCLUSTERS opt_param.h
NSFBUFS opt_param.h
VM_BCACHE_SIZE_MAX opt_param.h
VM_SWZONE_SIZE_MAX opt_param.h
MAXUSERS
# Generic SCSI options.

View File

@ -299,7 +299,9 @@ cpu_startup(dummy)
* 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/20 of our ram over 64MB.
* buffers to cover 1/20 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.
*/
@ -312,6 +314,9 @@ cpu_startup(dummy)
16384 / factor);
if (physmem_est > 16384)
nbuf += (physmem_est - 16384) * 2 / (factor * 5);
if (maxbcache && nbuf > physmem_est / BKVASIZE)
nbuf = maxbcache / BKVASIZE;
}
/*

View File

@ -112,6 +112,22 @@
#define IOPAGES 2 /* pages of i/o permission bitmap */
#define UPAGES 2 /* pages of u-area */
/*
* Ceiling on amount of swblock kva space.
*/
#ifndef VM_SWZONE_SIZE_MAX
#define VM_SWZONE_SIZE_MAX (70 * 1024 * 1024)
#endif
/*
* Ceiling on size of buffer cache (really only effects write queueing,
* the VM page cache is not effected).
*/
#ifndef VM_BCACHE_SIZE_MAX
#define VM_BCACHE_SIZE_MAX (200 * 1024 * 1024)
#endif
/*
* Constants related to network buffer management.
* MCLBYTES must be no larger than PAGE_SIZE.

View File

@ -72,6 +72,8 @@ int maxfilesperproc; /* per-proc open files limit */
int ncallout; /* maximum # of timer events */
int nbuf;
int nswbuf;
int maxswzone; /* max swmeta KVA storage */
int maxbcache; /* max buffer cache KVA storage */
/*
* These have to be allocated somewhere; allocating
@ -114,6 +116,10 @@ init_param(void)
/* Cannot be changed after boot */
nbuf = NBUF;
TUNABLE_INT_FETCH("kern.nbuf", &nbuf);
maxswzone = VM_SWZONE_SIZE_MAX;
TUNABLE_INT_FETCH("kern.maxswzone", &maxswzone);
maxbcache = VM_BCACHE_SIZE_MAX;
TUNABLE_INT_FETCH("kern.maxbcache", &maxbcache);
ncallout = 16 + maxproc + maxfiles;
TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
}

View File

@ -499,6 +499,8 @@ 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 buf_maxio; /* nominal maximum I/O for buffer */
extern struct buf *buf; /* The buffer headers. */

View File

@ -323,10 +323,13 @@ swap_pager_swap_init()
/*
* Initialize our zone. Right now I'm just guessing on the number
* we need based on the number of pages in the system. Each swblock
* can hold 16 pages, so this is probably overkill.
* can hold 16 pages, so this is probably overkill. This reservation
* is typically limited to around 70MB by default.
*/
n = min(cnt.v_page_count, (kernel_map->max_offset - kernel_map->min_offset) / PAGE_SIZE) * 2;
n = cnt.v_page_count;
if (maxswzone && n > maxswzone / sizeof(struct swblock))
n = maxswzone / sizeof(struct swblock);
n2 = n;
do {