xref: /dragonfly/sys/kern/subr_param.c (revision 655933d6)
1 /*
2  * Copyright (c) 1980, 1986, 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)param.c	8.3 (Berkeley) 8/20/94
35  * $FreeBSD: src/sys/kern/subr_param.c,v 1.42.2.10 2002/03/09 21:05:47 silby Exp $
36  */
37 
38 #include "opt_param.h"
39 #include "opt_maxusers.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/sysctl.h>
46 #include <vm/pmap.h>
47 #include <machine/vmparam.h>
48 
49 /*
50  * System parameter formulae.
51  */
52 
53 #ifndef HZ_DEFAULT
54 #define	HZ_DEFAULT	100
55 #endif
56 #define	NPROC		(20 + 16 * maxusers)
57 #ifndef NBUF
58 #define NBUF		0
59 #endif
60 #ifndef MAXFILES
61 #define	MAXFILES	(maxproc * 16)
62 #endif
63 #ifndef MAXPOSIXLOCKSPERUID
64 #define MAXPOSIXLOCKSPERUID (maxproc * 4)
65 #endif
66 
67 static int sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS);
68 
69 int	hz;
70 int	stathz;
71 int	profhz;
72 int	ustick;				/* tick interval in microseconds */
73 int	nstick;				/* tick interval in nanoseconds */
74 int	maxusers;			/* base tunable */
75 int	maxproc;			/* maximum # of processes */
76 int	maxprocperuid;			/* max # of procs per user */
77 int	maxfiles;			/* system wide open files limit */
78 int	maxfilesrootres;		/* descriptors reserved for root use */
79 int	minfilesperproc;		/* per-proc min open files (safety) */
80 int	maxfilesperproc;		/* per-proc open files limit */
81 int	maxfilesperuser;		/* per-user open files limit */
82 int	maxposixlocksperuid;		/* max # POSIX locks per uid */
83 int	ncallout;			/* maximum # of timer events */
84 int	mbuf_wait = 32;			/* mbuf sleep time in ticks */
85 long	nbuf;
86 long	nswbuf_mem;
87 long	nswbuf_kva;
88 long	nswbuf_raw;
89 long	maxswzone;			/* max swmeta KVA storage */
90 long	maxbcache;			/* max buffer cache KVA storage */
91 enum vmm_guest_type vmm_guest = VMM_GUEST_NONE;	/* Running as VM guest? */
92 u_quad_t	maxtsiz;			/* max text size */
93 u_quad_t	dfldsiz;			/* initial data size limit */
94 u_quad_t	maxdsiz;			/* max data size */
95 u_quad_t	dflssiz;			/* initial stack size limit */
96 u_quad_t	maxssiz;			/* max stack size */
97 u_quad_t	sgrowsiz;			/* amount to grow stack */
98 u_quad_t	maxthrssiz;			/* thread stack area */
99 
100 SYSCTL_PROC(_kern, OID_AUTO, vmm_guest, CTLFLAG_RD | CTLTYPE_STRING,
101 	    NULL, 0, sysctl_kern_vmm_guest, "A",
102 	    "Virtual machine guest type");
103 SYSCTL_QUAD(_kern, OID_AUTO, maxssiz, CTLFLAG_RD, &maxssiz, 0,
104 	    "Maximum user stack size");
105 SYSCTL_QUAD(_kern, OID_AUTO, maxthrssiz, CTLFLAG_RD, &maxthrssiz, 0,
106 	    "Nominal threading stack area");
107 
108 /*
109  * These have to be allocated somewhere; allocating
110  * them here forces loader errors if this file is omitted
111  * (if they've been externed everywhere else; hah!).
112  */
113 struct	buf *swbuf_mem;
114 struct	buf *swbuf_kva;
115 struct	buf *swbuf_raw;
116 
117 struct vmm_bname {
118 	const char *str;
119 	enum vmm_guest_type type;
120 };
121 
122 static struct vmm_bname vmm_bnames[] = {
123 	{ "QEMU",	VMM_GUEST_QEMU },	/* QEMU */
124 	{ "Plex86",	VMM_GUEST_PLEX86 },	/* Plex86 */
125 	{ "Bochs",	VMM_GUEST_BOCHS },	/* Bochs */
126 	{ "Xen",	VMM_GUEST_XEN },	/* Xen */
127 	{ "BHYVE",	VMM_GUEST_BHYVE },	/* bhyve */
128 	{ "Seabios",	VMM_GUEST_KVM},		/* KVM */
129 	{ NULL, 0 }
130 };
131 
132 static struct vmm_bname vmm_pnames[] = {
133 	{ "VMware Virtual Platform",	VMM_GUEST_VMWARE },	/* VMWare VM */
134 	{ "Virtual Machine",		VMM_GUEST_HYPERV },	/* MS Hyper-V */
135 	{ "VirtualBox",			VMM_GUEST_VBOX },	/* Sun VirtualBox */
136 	{ "Parallels Virtual Platform",	VMM_GUEST_PARALLELS },	/* Parallels VM */
137 	{ "KVM",			VMM_GUEST_KVM },	/* KVM */
138 	{ NULL, 0 }
139 };
140 
141 static const char *const vmm_guest_sysctl_names[] = {
142 	"none",
143 	"qemu",
144 	"plex86",
145 	"bochs",
146 	"xen",
147 	"bhyve",
148 	"kvm",
149 	"vmware",
150 	"hyperv",
151 	"vbox",
152 	"parallels",
153 	"vkernel",
154 	"nvmm",
155 	"unknown",
156 	NULL
157 };
158 CTASSERT(NELEM(vmm_guest_sysctl_names) - 1 == VMM_GUEST_LAST);
159 
160 char		vmm_vendor[16];
161 SYSCTL_STRING(_kern, OID_AUTO, vmm_vendor, CTLFLAG_RD, vmm_vendor, 0,
162     "Virtual machine vendor");
163 
164 /*
165  * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
166  */
167 enum vmm_guest_type
168 detect_virtual(void)
169 {
170 	char *sysenv;
171 	int i;
172 
173 	sysenv = kgetenv("smbios.bios.vendor");
174 	if (sysenv != NULL) {
175 		for (i = 0; vmm_bnames[i].str != NULL; i++)
176 			if (strcmp(sysenv, vmm_bnames[i].str) == 0) {
177 				kfreeenv(sysenv);
178 				return (vmm_bnames[i].type);
179 			}
180 		kfreeenv(sysenv);
181 	}
182 	sysenv = kgetenv("smbios.system.product");
183 	if (sysenv != NULL) {
184 		for (i = 0; vmm_pnames[i].str != NULL; i++)
185 			if (strcmp(sysenv, vmm_pnames[i].str) == 0) {
186 				kfreeenv(sysenv);
187 				return (vmm_pnames[i].type);
188 			}
189 		kfreeenv(sysenv);
190 	}
191 	return (VMM_GUEST_NONE);
192 }
193 
194 /*
195  * Boot time overrides that are not scaled against main memory
196  */
197 void
198 init_param1(void)
199 {
200 	hz = HZ_DEFAULT;
201 	TUNABLE_INT_FETCH("kern.hz", &hz);
202 	stathz = hz + 1;
203 	TUNABLE_INT_FETCH("kern.stathz", &stathz);
204 	profhz = stathz;
205 	ustick = 1000000 / hz;
206 	nstick = 1000000000 / hz;
207 	/* can adjust 30ms in 60s */
208 	ntp_default_tick_delta = howmany(30000000, 60 * hz);
209 
210 #ifdef VM_SWZONE_SIZE_MAX
211 	maxswzone = VM_SWZONE_SIZE_MAX;
212 #endif
213 	TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
214 #ifdef VM_BCACHE_SIZE_MAX
215 	maxbcache = VM_BCACHE_SIZE_MAX;
216 #endif
217 	TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
218 	maxtsiz = MAXTSIZ;
219 	TUNABLE_QUAD_FETCH("kern.maxtsiz", &maxtsiz);
220 	dfldsiz = DFLDSIZ;
221 	TUNABLE_QUAD_FETCH("kern.dfldsiz", &dfldsiz);
222 	maxdsiz = MAXDSIZ;
223 	TUNABLE_QUAD_FETCH("kern.maxdsiz", &maxdsiz);
224 	dflssiz = DFLSSIZ;
225 	TUNABLE_QUAD_FETCH("kern.dflssiz", &dflssiz);
226 	maxssiz = MAXSSIZ;
227 	TUNABLE_QUAD_FETCH("kern.maxssiz", &maxssiz);
228 	sgrowsiz = SGROWSIZ;
229 	TUNABLE_QUAD_FETCH("kern.sgrowsiz", &sgrowsiz);
230 	maxthrssiz = MAXTHRSSIZ;
231 	TUNABLE_QUAD_FETCH("kern.maxthrssiz", &maxthrssiz);
232 }
233 
234 /*
235  * Boot time overrides that are scaled against main memory
236  */
237 void
238 init_param2(int physpages)
239 {
240 	size_t limsize;
241 
242 	/*
243 	 * Calculate manually becaus the VM page queues / system is not set
244 	 * up yet.
245 	 */
246 	limsize = (size_t)physpages * PAGE_SIZE;
247 	if (limsize > KvaSize)
248 		limsize = KvaSize;
249 	if (maxswzone > limsize / 2)	/* maxswzone size (1/2 of phys mem) */
250 		maxswzone = limsize / 2;
251 
252 	limsize /= 1024 * 1024;		/* smaller of KVM or physmem in MB */
253 
254 	/* Base parameters */
255 	maxusers = MAXUSERS;
256 	TUNABLE_INT_FETCH("kern.maxusers", &maxusers);
257 	if (maxusers == 0) {
258 		maxusers = limsize / 8;		/* ~384 per 3G */
259 		if (maxusers < 32)
260 			maxusers = 32;
261 		/* no upper limit */
262 	}
263 
264 	/*
265 	 * The following can be overridden after boot via sysctl.  Note:
266 	 * unless overridden, these macros are ultimately based on maxusers.
267 	 *
268 	 * Limit maxproc so that kmap entries cannot be exhausted by
269 	 * processes.  This limitation can be a bit problematic because
270 	 * processes can have a wide range of complexity.
271 	 */
272 	maxproc = NPROC;
273 	TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
274 	if (maxproc < 32)
275 		maxproc = 32;
276 	if (maxproc > limsize * 40)
277 		maxproc = limsize * 40;
278 
279 	/*
280 	 * Maximum number of open files
281 	 */
282 	maxfiles = MAXFILES;
283 	TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
284 	if (maxfiles < 128)
285 		maxfiles = 128;
286 
287 	/*
288 	 * Limit file descriptors so no single user can exhaust the
289 	 * system.
290 	 *
291 	 * WARNING: Do not set minfilesperproc too high or the user
292 	 *	    can exhaust the system with a combination of fork()
293 	 *	    and open().  Actual worst case is:
294 	 *
295 	 *	    (minfilesperproc * maxprocperuid) + maxfilesperuser
296 	 */
297 	maxprocperuid = maxproc / 4;
298 	if (maxprocperuid < 128)
299 		maxprocperuid = maxproc / 2;
300 	minfilesperproc = 8;
301 	maxfilesperproc = maxfiles / 4;
302 	maxfilesperuser = maxfilesperproc * 2;
303 	maxfilesrootres = maxfiles / 20;
304 
305 	/*
306 	 * Severe hack to try to prevent pipe() descriptors from
307 	 * blowing away kernel memory.
308 	 */
309 	if (KvaSize <= (vm_offset_t)(1536LL * 1024 * 1024) &&
310 	    maxfilesperuser > 20000) {
311 		maxfilesperuser = 20000;
312 	}
313 
314 	maxposixlocksperuid = MAXPOSIXLOCKSPERUID;
315 	TUNABLE_INT_FETCH("kern.maxposixlocksperuid", &maxposixlocksperuid);
316 
317 	/*
318 	 * Unless overridden, NBUF is typically 0 (auto-sized later).
319 	 */
320 	nbuf = NBUF;
321 	TUNABLE_LONG_FETCH("kern.nbuf", &nbuf);
322 
323 	/*
324 	 * Calculate the size of the callout wheel.  Limit to approximately
325 	 * 5 minutes worth of table (maxproc would have to be pretty huge),
326 	 * as more is not likely to gain us anything.
327 	 */
328 	ncallout = 16 + maxproc + maxfiles;
329 	if (ncallout > 5*60*hz)
330 		ncallout = 5*60*hz;
331 	TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
332 }
333 
334 /*
335  * Sysctl stringifying handler for kern.vmm_guest.
336  */
337 static int
338 sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)
339 {
340 	return (SYSCTL_OUT(req, vmm_guest_sysctl_names[vmm_guest],
341 	    strlen(vmm_guest_sysctl_names[vmm_guest])));
342 }
343