e9a3f7852d
Also, express this new maximum as a fraction of the kernel's address space size rather than a constant so that increasing KVA_PAGES will automatically increase this maximum. As a side-effect of this change, kern.maxvnodes will automatically increase by a proportional amount. While I'm here ensure that this change doesn't result in an unintended increase in maxpipekva on i386. Calculate maxpipekva based upon the size of the kernel address space and the amount of physical memory instead of the size of the kmem map. The memory backing pipes is not allocated from the kmem map. It is allocated from its own submap of the kernel map. In short, it has no real connection to the kmem map. (In fact, the commit messages for the maxpipekva auto-sizing talk about using the kernel map size, cf. r117325 and r117391, even though the implementation actually used the kmem map size.) Although the calculation is now done differently, the resulting value for maxpipekva should remain almost the same on i386. However, on amd64, the value will be reduced by 2/3. This is intentional. The recent change to VM_KMEM_SIZE_SCALE on amd64 for the benefit of ZFS also had the unnecessary side-effect of increasing maxpipekva. This change is effectively restoring maxpipekva on amd64 to its prior value. Eliminate init_param3() since it is no longer used.
321 lines
9.4 KiB
C
321 lines
9.4 KiB
C
/*-
|
|
* Copyright (c) 1980, 1986, 1989, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
* (c) UNIX System Laboratories, Inc.
|
|
* All or some portions of this file are derived from material licensed
|
|
* to the University of California by American Telephone and Telegraph
|
|
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
|
* the permission of UNIX System Laboratories, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* @(#)param.c 8.3 (Berkeley) 8/20/94
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include "opt_param.h"
|
|
#include "opt_msgbuf.h"
|
|
#include "opt_maxusers.h"
|
|
|
|
#include <sys/limits.h>
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/kernel.h>
|
|
#include <sys/sysctl.h>
|
|
#include <sys/msgbuf.h>
|
|
|
|
#include <vm/vm.h>
|
|
#include <vm/vm_param.h>
|
|
#include <vm/pmap.h>
|
|
|
|
/*
|
|
* System parameter formulae.
|
|
*/
|
|
|
|
#ifndef HZ
|
|
# if defined(__mips__) || defined(__arm__)
|
|
# define HZ 100
|
|
# else
|
|
# define HZ 1000
|
|
# endif
|
|
# ifndef HZ_VM
|
|
# define HZ_VM 100
|
|
# endif
|
|
#else
|
|
# ifndef HZ_VM
|
|
# define HZ_VM HZ
|
|
# endif
|
|
#endif
|
|
#define NPROC (20 + 16 * maxusers)
|
|
#ifndef NBUF
|
|
#define NBUF 0
|
|
#endif
|
|
#ifndef MAXFILES
|
|
#define MAXFILES (maxproc * 2)
|
|
#endif
|
|
|
|
static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS);
|
|
|
|
int hz;
|
|
int tick;
|
|
int maxusers; /* base tunable */
|
|
int maxproc; /* maximum # of processes */
|
|
int maxprocperuid; /* max # of procs per user */
|
|
int maxfiles; /* sys. wide open files limit */
|
|
int maxfilesperproc; /* per-proc open files limit */
|
|
int msgbufsize; /* size of kernel message buffer */
|
|
int ncallout; /* maximum # of timer events */
|
|
int nbuf;
|
|
int ngroups_max; /* max # groups per process */
|
|
int nswbuf;
|
|
long maxswzone; /* max swmeta KVA storage */
|
|
long maxbcache; /* max buffer cache KVA storage */
|
|
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 */
|
|
u_long maxdsiz; /* max data size */
|
|
u_long dflssiz; /* initial stack size limit */
|
|
u_long maxssiz; /* max stack size */
|
|
u_long sgrowsiz; /* amount to grow stack */
|
|
|
|
SYSCTL_INT(_kern, OID_AUTO, hz, CTLFLAG_RDTUN, &hz, 0,
|
|
"Number of clock ticks per second");
|
|
SYSCTL_INT(_kern, OID_AUTO, ncallout, CTLFLAG_RDTUN, &ncallout, 0,
|
|
"Number of pre-allocated timer events");
|
|
SYSCTL_INT(_kern, OID_AUTO, nbuf, CTLFLAG_RDTUN, &nbuf, 0,
|
|
"Number of buffers in the buffer cache");
|
|
SYSCTL_INT(_kern, OID_AUTO, nswbuf, CTLFLAG_RDTUN, &nswbuf, 0,
|
|
"Number of swap buffers");
|
|
SYSCTL_INT(_kern, OID_AUTO, msgbufsize, CTLFLAG_RDTUN, &msgbufsize, 0,
|
|
"Size of the kernel message buffer");
|
|
SYSCTL_LONG(_kern, OID_AUTO, maxswzone, CTLFLAG_RDTUN, &maxswzone, 0,
|
|
"Maximum memory for swap metadata");
|
|
SYSCTL_LONG(_kern, OID_AUTO, maxbcache, CTLFLAG_RDTUN, &maxbcache, 0,
|
|
"Maximum value of vfs.maxbufspace");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, maxtsiz, CTLFLAG_RDTUN, &maxtsiz, 0,
|
|
"Maximum text size");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, dfldsiz, CTLFLAG_RDTUN, &dfldsiz, 0,
|
|
"Initial data size limit");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, maxdsiz, CTLFLAG_RDTUN, &maxdsiz, 0,
|
|
"Maximum data size");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, dflssiz, CTLFLAG_RDTUN, &dflssiz, 0,
|
|
"Initial stack size limit");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, maxssiz, CTLFLAG_RDTUN, &maxssiz, 0,
|
|
"Maximum stack size");
|
|
SYSCTL_ULONG(_kern, OID_AUTO, sgrowsiz, CTLFLAG_RDTUN, &sgrowsiz, 0,
|
|
"Amount to grow stack on a stack fault");
|
|
SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING,
|
|
NULL, 0, sysctl_kern_vm_guest, "A",
|
|
"Virtual machine guest detected? (none|generic|xen)");
|
|
|
|
/*
|
|
* These have to be allocated somewhere; allocating
|
|
* them here forces loader errors if this file is omitted
|
|
* (if they've been externed everywhere else; hah!).
|
|
*/
|
|
struct buf *swbuf;
|
|
|
|
/*
|
|
* The elements of this array are ordered based upon the values of the
|
|
* corresponding enum VM_GUEST members.
|
|
*/
|
|
static const char *const vm_guest_sysctl_names[] = {
|
|
"none",
|
|
"generic",
|
|
"xen",
|
|
NULL
|
|
};
|
|
|
|
#ifndef XEN
|
|
static const char *const vm_bnames[] = {
|
|
"QEMU", /* QEMU */
|
|
"Plex86", /* Plex86 */
|
|
"Bochs", /* Bochs */
|
|
"Xen", /* Xen */
|
|
NULL
|
|
};
|
|
|
|
static const char *const vm_pnames[] = {
|
|
"VMware Virtual Platform", /* VMWare VM */
|
|
"Virtual Machine", /* Microsoft VirtualPC */
|
|
"VirtualBox", /* Sun xVM VirtualBox */
|
|
"Parallels Virtual Platform", /* Parallels VM */
|
|
NULL
|
|
};
|
|
|
|
|
|
/*
|
|
* Detect known Virtual Machine hosts by inspecting the emulated BIOS.
|
|
*/
|
|
static enum VM_GUEST
|
|
detect_virtual(void)
|
|
{
|
|
char *sysenv;
|
|
int i;
|
|
|
|
sysenv = getenv("smbios.bios.vendor");
|
|
if (sysenv != NULL) {
|
|
for (i = 0; vm_bnames[i] != NULL; i++)
|
|
if (strcmp(sysenv, vm_bnames[i]) == 0) {
|
|
freeenv(sysenv);
|
|
return (VM_GUEST_VM);
|
|
}
|
|
freeenv(sysenv);
|
|
}
|
|
sysenv = getenv("smbios.system.product");
|
|
if (sysenv != NULL) {
|
|
for (i = 0; vm_pnames[i] != NULL; i++)
|
|
if (strcmp(sysenv, vm_pnames[i]) == 0) {
|
|
freeenv(sysenv);
|
|
return (VM_GUEST_VM);
|
|
}
|
|
freeenv(sysenv);
|
|
}
|
|
return (VM_GUEST_NO);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Boot time overrides that are not scaled against main memory
|
|
*/
|
|
void
|
|
init_param1(void)
|
|
{
|
|
#ifndef XEN
|
|
vm_guest = detect_virtual();
|
|
#else
|
|
vm_guest = VM_GUEST_XEN;
|
|
#endif
|
|
hz = -1;
|
|
TUNABLE_INT_FETCH("kern.hz", &hz);
|
|
if (hz == -1)
|
|
hz = vm_guest > VM_GUEST_NO ? HZ_VM : HZ;
|
|
tick = 1000000 / hz;
|
|
|
|
#ifdef VM_SWZONE_SIZE_MAX
|
|
maxswzone = VM_SWZONE_SIZE_MAX;
|
|
#endif
|
|
TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
|
|
#ifdef VM_BCACHE_SIZE_MAX
|
|
maxbcache = VM_BCACHE_SIZE_MAX;
|
|
#endif
|
|
TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
|
|
msgbufsize = MSGBUF_SIZE;
|
|
TUNABLE_INT_FETCH("kern.msgbufsize", &msgbufsize);
|
|
|
|
maxtsiz = MAXTSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.maxtsiz", &maxtsiz);
|
|
dfldsiz = DFLDSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.dfldsiz", &dfldsiz);
|
|
maxdsiz = MAXDSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.maxdsiz", &maxdsiz);
|
|
dflssiz = DFLSSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.dflssiz", &dflssiz);
|
|
maxssiz = MAXSSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.maxssiz", &maxssiz);
|
|
sgrowsiz = SGROWSIZ;
|
|
TUNABLE_ULONG_FETCH("kern.sgrowsiz", &sgrowsiz);
|
|
|
|
/*
|
|
* Let the administrator set {NGROUPS_MAX}, but disallow values
|
|
* less than NGROUPS_MAX which would violate POSIX.1-2008 or
|
|
* greater than INT_MAX-1 which would result in overflow.
|
|
*/
|
|
ngroups_max = NGROUPS_MAX;
|
|
TUNABLE_INT_FETCH("kern.ngroups", &ngroups_max);
|
|
if (ngroups_max < NGROUPS_MAX)
|
|
ngroups_max = NGROUPS_MAX;
|
|
}
|
|
|
|
/*
|
|
* Boot time overrides that are scaled against main memory
|
|
*/
|
|
void
|
|
init_param2(long physpages)
|
|
{
|
|
|
|
/* Base parameters */
|
|
maxusers = MAXUSERS;
|
|
TUNABLE_INT_FETCH("kern.maxusers", &maxusers);
|
|
if (maxusers == 0) {
|
|
maxusers = physpages / (2 * 1024 * 1024 / PAGE_SIZE);
|
|
if (maxusers < 32)
|
|
maxusers = 32;
|
|
if (maxusers > 384)
|
|
maxusers = 384;
|
|
}
|
|
|
|
/*
|
|
* The following can be overridden after boot via sysctl. Note:
|
|
* unless overriden, these macros are ultimately based on maxusers.
|
|
*/
|
|
maxproc = NPROC;
|
|
TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
|
|
/*
|
|
* Limit maxproc so that kmap entries cannot be exhausted by
|
|
* processes.
|
|
*/
|
|
if (maxproc > (physpages / 12))
|
|
maxproc = physpages / 12;
|
|
maxfiles = MAXFILES;
|
|
TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
|
|
maxprocperuid = (maxproc * 9) / 10;
|
|
maxfilesperproc = (maxfiles * 9) / 10;
|
|
|
|
/*
|
|
* Cannot be changed after boot.
|
|
*/
|
|
nbuf = NBUF;
|
|
TUNABLE_INT_FETCH("kern.nbuf", &nbuf);
|
|
|
|
ncallout = 16 + maxproc + maxfiles;
|
|
TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
|
|
|
|
/*
|
|
* The default for maxpipekva is min(1/64 of the kernel address space,
|
|
* max(1/64 of main memory, 512KB)). See sys_pipe.c for more details.
|
|
*/
|
|
maxpipekva = (physpages / 64) * PAGE_SIZE;
|
|
if (maxpipekva < 512 * 1024)
|
|
maxpipekva = 512 * 1024;
|
|
if (maxpipekva > (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 64)
|
|
maxpipekva = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) /
|
|
64;
|
|
TUNABLE_LONG_FETCH("kern.ipc.maxpipekva", &maxpipekva);
|
|
}
|
|
|
|
/*
|
|
* Sysctl stringiying handler for kern.vm_guest.
|
|
*/
|
|
static int
|
|
sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS)
|
|
{
|
|
return (SYSCTL_OUT(req, vm_guest_sysctl_names[vm_guest],
|
|
strlen(vm_guest_sysctl_names[vm_guest])));
|
|
}
|