xref: /dragonfly/sys/kern/subr_param.c (revision 6b47f3ea)
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 long	nbuf;
85 long	nswbuf_mem;
86 long	nswbuf_kva;
87 long	nswbuf_raw;
88 long	maxswzone;			/* max swmeta KVA storage */
89 long	maxbcache;			/* max buffer cache KVA storage */
90 enum vmm_guest_type vmm_guest = VMM_GUEST_NONE;	/* Running as VM guest? */
91 u_quad_t	maxtsiz;			/* max text size */
92 u_quad_t	dfldsiz;			/* initial data size limit */
93 u_quad_t	maxdsiz;			/* max data size */
94 u_quad_t	dflssiz;			/* initial stack size limit */
95 u_quad_t	maxssiz;			/* max stack size */
96 u_quad_t	sgrowsiz;			/* amount to grow stack */
97 u_quad_t	maxthrssiz;			/* thread stack area */
98 
99 SYSCTL_PROC(_kern, OID_AUTO, vmm_guest, CTLFLAG_RD | CTLTYPE_STRING,
100 	    NULL, 0, sysctl_kern_vmm_guest, "A",
101 	    "Virtual machine guest type");
102 SYSCTL_QUAD(_kern, OID_AUTO, maxssiz, CTLFLAG_RD, &maxssiz, 0,
103 	    "Maximum user stack size");
104 SYSCTL_QUAD(_kern, OID_AUTO, maxthrssiz, CTLFLAG_RD, &maxthrssiz, 0,
105 	    "Nominal threading stack area");
106 
107 /*
108  * These have to be allocated somewhere; allocating
109  * them here forces loader errors if this file is omitted
110  * (if they've been externed everywhere else; hah!).
111  */
112 struct	buf *swbuf_mem;
113 struct	buf *swbuf_kva;
114 struct	buf *swbuf_raw;
115 
116 struct vmm_bname {
117 	const char *str;
118 	enum vmm_guest_type type;
119 };
120 
121 static struct vmm_bname vmm_bnames[] = {
122 	{ "QEMU",	VMM_GUEST_QEMU },	/* QEMU */
123 	{ "Plex86",	VMM_GUEST_PLEX86 },	/* Plex86 */
124 	{ "Bochs",	VMM_GUEST_BOCHS },	/* Bochs */
125 	{ "Xen",	VMM_GUEST_XEN },	/* Xen */
126 	{ "BHYVE",	VMM_GUEST_BHYVE },	/* bhyve */
127 	{ "Seabios",	VMM_GUEST_KVM},		/* KVM */
128 	{ NULL, 0 }
129 };
130 
131 static struct vmm_bname vmm_pnames[] = {
132 	{ "VMware Virtual Platform",	VMM_GUEST_VMWARE },	/* VMWare VM */
133 	{ "Virtual Machine",		VMM_GUEST_HYPERV },	/* MS Hyper-V */
134 	{ "VirtualBox",			VMM_GUEST_VBOX },	/* Sun VirtualBox */
135 	{ "Parallels Virtual Platform",	VMM_GUEST_PARALLELS },	/* Parallels VM */
136 	{ "KVM",			VMM_GUEST_KVM },	/* KVM */
137 	{ NULL, 0 }
138 };
139 
140 static const char *const vmm_guest_sysctl_names[] = {
141 	"none",
142 	"qemu",
143 	"plex86",
144 	"bochs",
145 	"xen",
146 	"bhyve",
147 	"kvm",
148 	"vmware",
149 	"hyperv",
150 	"vbox",
151 	"parallels",
152 	"vkernel",
153 	"nvmm",
154 	"unknown",
155 	NULL
156 };
157 CTASSERT(NELEM(vmm_guest_sysctl_names) - 1 == VMM_GUEST_LAST);
158 
159 char		vmm_vendor[16];
160 SYSCTL_STRING(_kern, OID_AUTO, vmm_vendor, CTLFLAG_RD, vmm_vendor, 0,
161     "Virtual machine vendor");
162 
163 /*
164  * Detect known Virtual Machine hosts by inspecting the emulated BIOS.
165  */
166 enum vmm_guest_type
167 detect_virtual(void)
168 {
169 	char *sysenv;
170 	int i;
171 
172 	sysenv = kgetenv("smbios.bios.vendor");
173 	if (sysenv != NULL) {
174 		for (i = 0; vmm_bnames[i].str != NULL; i++)
175 			if (strcmp(sysenv, vmm_bnames[i].str) == 0) {
176 				kfreeenv(sysenv);
177 				return (vmm_bnames[i].type);
178 			}
179 		kfreeenv(sysenv);
180 	}
181 	sysenv = kgetenv("smbios.system.product");
182 	if (sysenv != NULL) {
183 		for (i = 0; vmm_pnames[i].str != NULL; i++)
184 			if (strcmp(sysenv, vmm_pnames[i].str) == 0) {
185 				kfreeenv(sysenv);
186 				return (vmm_pnames[i].type);
187 			}
188 		kfreeenv(sysenv);
189 	}
190 	return (VMM_GUEST_NONE);
191 }
192 
193 /*
194  * Boot time overrides that are not scaled against main memory
195  */
196 void
197 init_param1(void)
198 {
199 	hz = HZ_DEFAULT;
200 	TUNABLE_INT_FETCH("kern.hz", &hz);
201 	stathz = hz + 1;
202 	TUNABLE_INT_FETCH("kern.stathz", &stathz);
203 	profhz = stathz;
204 	ustick = 1000000 / hz;
205 	nstick = 1000000000 / hz;
206 	/* can adjust 30ms in 60s */
207 	ntp_default_tick_delta = howmany(30000000, 60 * hz);
208 
209 #ifdef VM_SWZONE_SIZE_MAX
210 	maxswzone = VM_SWZONE_SIZE_MAX;
211 #endif
212 	TUNABLE_LONG_FETCH("kern.maxswzone", &maxswzone);
213 #ifdef VM_BCACHE_SIZE_MAX
214 	maxbcache = VM_BCACHE_SIZE_MAX;
215 #endif
216 	TUNABLE_LONG_FETCH("kern.maxbcache", &maxbcache);
217 	maxtsiz = MAXTSIZ;
218 	TUNABLE_QUAD_FETCH("kern.maxtsiz", &maxtsiz);
219 	dfldsiz = DFLDSIZ;
220 	TUNABLE_QUAD_FETCH("kern.dfldsiz", &dfldsiz);
221 	maxdsiz = MAXDSIZ;
222 	TUNABLE_QUAD_FETCH("kern.maxdsiz", &maxdsiz);
223 	dflssiz = DFLSSIZ;
224 	TUNABLE_QUAD_FETCH("kern.dflssiz", &dflssiz);
225 	maxssiz = MAXSSIZ;
226 	TUNABLE_QUAD_FETCH("kern.maxssiz", &maxssiz);
227 	sgrowsiz = SGROWSIZ;
228 	TUNABLE_QUAD_FETCH("kern.sgrowsiz", &sgrowsiz);
229 	maxthrssiz = MAXTHRSSIZ;
230 	TUNABLE_QUAD_FETCH("kern.maxthrssiz", &maxthrssiz);
231 }
232 
233 /*
234  * Boot time overrides that are scaled against main memory
235  */
236 void
237 init_param2(int physpages)
238 {
239 	size_t limsize;
240 
241 	/*
242 	 * Calculate manually becaus the VM page queues / system is not set
243 	 * up yet.
244 	 */
245 	limsize = (size_t)physpages * PAGE_SIZE;
246 	if (limsize > KvaSize)
247 		limsize = KvaSize;
248 	if (maxswzone > limsize / 2)	/* maxswzone size (1/2 of phys mem) */
249 		maxswzone = limsize / 2;
250 
251 	limsize /= 1024 * 1024;		/* smaller of KVM or physmem in MB */
252 
253 	/* Base parameters */
254 	maxusers = MAXUSERS;
255 	TUNABLE_INT_FETCH("kern.maxusers", &maxusers);
256 	if (maxusers == 0) {
257 		maxusers = limsize / 8;		/* ~384 per 3G */
258 		if (maxusers < 32)
259 			maxusers = 32;
260 		/* no upper limit */
261 	}
262 
263 	/*
264 	 * The following can be overridden after boot via sysctl.  Note:
265 	 * unless overridden, these macros are ultimately based on maxusers.
266 	 *
267 	 * Limit maxproc so that kmap entries cannot be exhausted by
268 	 * processes.  This limitation can be a bit problematic because
269 	 * processes can have a wide range of complexity.
270 	 */
271 	maxproc = NPROC;
272 	TUNABLE_INT_FETCH("kern.maxproc", &maxproc);
273 	if (maxproc < 32)
274 		maxproc = 32;
275 	if (maxproc > limsize * 40)
276 		maxproc = limsize * 40;
277 
278 	/*
279 	 * Maximum number of open files
280 	 */
281 	maxfiles = MAXFILES;
282 	TUNABLE_INT_FETCH("kern.maxfiles", &maxfiles);
283 	if (maxfiles < 128)
284 		maxfiles = 128;
285 
286 	/*
287 	 * Limit file descriptors so no single user can exhaust the
288 	 * system.
289 	 *
290 	 * WARNING: Do not set minfilesperproc too high or the user
291 	 *	    can exhaust the system with a combination of fork()
292 	 *	    and open().  Actual worst case is:
293 	 *
294 	 *	    (minfilesperproc * maxprocperuid) + maxfilesperuser
295 	 */
296 	maxprocperuid = maxproc / 4;
297 	if (maxprocperuid < 128)
298 		maxprocperuid = maxproc / 2;
299 	minfilesperproc = 8;
300 	maxfilesperproc = maxfiles / 4;
301 	maxfilesperuser = maxfilesperproc * 2;
302 	maxfilesrootres = maxfiles / 20;
303 
304 	/*
305 	 * Severe hack to try to prevent pipe() descriptors from
306 	 * blowing away kernel memory.
307 	 */
308 	if (KvaSize <= (vm_offset_t)(1536LL * 1024 * 1024) &&
309 	    maxfilesperuser > 20000) {
310 		maxfilesperuser = 20000;
311 	}
312 
313 	maxposixlocksperuid = MAXPOSIXLOCKSPERUID;
314 	TUNABLE_INT_FETCH("kern.maxposixlocksperuid", &maxposixlocksperuid);
315 
316 	/*
317 	 * Unless overridden, NBUF is typically 0 (auto-sized later).
318 	 */
319 	nbuf = NBUF;
320 	TUNABLE_LONG_FETCH("kern.nbuf", &nbuf);
321 
322 	/*
323 	 * Calculate the size of the callout wheel.  Limit to approximately
324 	 * 5 minutes worth of table (maxproc would have to be pretty huge),
325 	 * as more is not likely to gain us anything.
326 	 */
327 	ncallout = 16 + maxproc + maxfiles;
328 	if (ncallout > 5*60*hz)
329 		ncallout = 5*60*hz;
330 	TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
331 }
332 
333 /*
334  * Sysctl stringifying handler for kern.vmm_guest.
335  */
336 static int
337 sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)
338 {
339 	return (SYSCTL_OUT(req, vmm_guest_sysctl_names[vmm_guest],
340 	    strlen(vmm_guest_sysctl_names[vmm_guest])));
341 }
342