xref: /dragonfly/sys/kern/subr_param.c (revision b272101acc636ac635f83d03265ef6a44a3ba51a)
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
detect_virtual(void)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
init_param1(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
init_param2(int physpages)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
sysctl_kern_vmm_guest(SYSCTL_HANDLER_ARGS)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