param.c revision 11134:8aa0c4ca6639
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/types.h>
27#include <sys/time.h>
28#include <sys/param.h>
29#include <sys/systm.h>
30#include <sys/signal.h>
31#include <sys/sysmacros.h>
32#include <sys/cmn_err.h>
33#include <sys/user.h>
34#include <sys/proc.h>
35#include <sys/task.h>
36#include <sys/project.h>
37#include <sys/klwp.h>
38#include <sys/vnode.h>
39#include <sys/file.h>
40#include <sys/fcntl.h>
41#include <sys/flock.h>
42#include <sys/var.h>
43#include <sys/stream.h>
44#include <sys/strsubr.h>
45#include <sys/conf.h>
46#include <sys/class.h>
47#include <sys/ts.h>
48#include <sys/rt.h>
49#include <sys/exec.h>
50#include <sys/exechdr.h>
51#include <sys/buf.h>
52#include <sys/resource.h>
53#include <vm/seg.h>
54#include <vm/pvn.h>
55#include <vm/seg_kmem.h>
56#include <sys/vmparam.h>
57#include <sys/machparam.h>
58#include <sys/utsname.h>
59#include <sys/kmem.h>
60#include <sys/stack.h>
61#include <sys/modctl.h>
62#include <sys/fdbuffer.h>
63#include <sys/cyclic_impl.h>
64#include <sys/disp.h>
65#include <sys/tuneable.h>
66#include <sys/systeminfo.h>
67
68#include <sys/vmem.h>
69#include <sys/clock.h>
70#include <sys/clock_impl.h>
71#include <sys/serializer.h>
72
73/*
74 * The following few lines describe generic things that must be compiled
75 * into the booted executable (unix) rather than genunix or any other
76 * module because they're required by crash dump readers, etc.
77 */
78struct modctl modules;		/* head of linked list of modules */
79char *default_path;		/* default module loading path */
80struct swapinfo *swapinfo;	/* protected by the swapinfo_lock */
81proc_t *practive;		/* active process list */
82uint_t nproc;			/* current number of processes */
83proc_t p0;			/* process 0 */
84struct plock p0lock;		/* p0's p_lock */
85klwp_t lwp0;			/* t0's lwp */
86task_t *task0p;			/* task 0 */
87kproject_t *proj0p;		/* location of project 0 */
88
89/*
90 * The following are "implementation architecture" dependent constants made
91 * available here in the form of initialized data for use by "implementation
92 * architecture" independent modules. See machparam.h.
93 */
94const unsigned long	_pagesize	= (unsigned long)PAGESIZE;
95const unsigned int	_pageshift	= (unsigned int)PAGESHIFT;
96const unsigned long	_pageoffset	= (unsigned long)PAGEOFFSET;
97/*
98 * XXX - This value pagemask has to be a 64bit size because
99 * large file support uses this mask on offsets which are 64 bit size.
100 * using unsigned leaves the higher 32 bits value as zero thus
101 * corrupting offset calculations in the file system and VM.
102 */
103const u_longlong_t	_pagemask	= (u_longlong_t)PAGEMASK;
104const unsigned long	_mmu_pagesize	= (unsigned long)MMU_PAGESIZE;
105const unsigned int	_mmu_pageshift	= (unsigned int)MMU_PAGESHIFT;
106const unsigned long	_mmu_pageoffset	= (unsigned long)MMU_PAGEOFFSET;
107const unsigned long	_mmu_pagemask	= (unsigned long)MMU_PAGEMASK;
108uintptr_t		_kernelbase	= (uintptr_t)KERNELBASE;
109uintptr_t		_userlimit	= (uintptr_t)USERLIMIT;
110uintptr_t		_userlimit32	= (uintptr_t)USERLIMIT32;
111const uintptr_t		_argsbase	= (uintptr_t)ARGSBASE;
112const unsigned int	_diskrpm	= (unsigned int)DISKRPM;
113const unsigned long	_pgthresh	= (unsigned long)PGTHRESH;
114const unsigned int	_maxslp		= (unsigned int)MAXSLP;
115const unsigned long	_maxhandspreadpages = (unsigned long)MAXHANDSPREADPAGES;
116const int		_ncpu 		= (int)NCPU;
117const unsigned long	_defaultstksz	= (unsigned long)DEFAULTSTKSZ;
118const unsigned int	_nbpg		= (unsigned int)MMU_PAGESIZE;
119
120/*
121 * System parameter formulae.
122 *
123 * This file is copied into each directory where we compile
124 * the kernel; it should be modified there to suit local taste
125 * if necessary.
126 */
127
128/*
129 * Default hz is 100, but if we set hires_tick we get higher resolution
130 * clock behavior (currently defined to be 1000 hz).  Higher values seem
131 * to work, but are not supported.
132 *
133 * If we do decide to play with higher values, remember that hz should
134 * satisfy the following constraints to avoid integer round-off problems:
135 *
136 * (1) hz should be in the range 100 <= hz <= MICROSEC.  If hz exceeds
137 *     MICROSEC, usec_per_tick will be zero and lots of stuff will break.
138 *     Similarly, if hz < 100 then hz / 100 == 0 and stuff will break.
139 *
140 * (2) If hz <= 1000, it should be both a multiple of 100 and a
141 *	divisor of 1000.
142 *
143 * (3) If hz > 1000, it should be both a multiple of 1000 and a
144 *	divisor of MICROSEC.
145 *
146 * Thus the only reasonable values of hz (i.e. the values that won't
147 * cause roundoff error) are: 100, 200, 500, 1000, 2000, 4000, 5000,
148 * 8000, 10000, 20000, 25000, 40000, 50000, 100000, 125000, 200000,
149 * 250000, 500000, 1000000.  As of this writing (1996) a clock rate
150 * of more than about 10 kHz seems utterly ridiculous, although
151 * this observation will no doubt seem quaintly amusing one day.
152 */
153#define	HIRES_HZ_DEFAULT	1000
154
155int hz = HZ_DEFAULT;
156int hires_hz = HIRES_HZ_DEFAULT;
157
158int hires_tick = 0;
159int cpu_decay_factor = 10;	/* this is no longer tied to clock */
160int max_hres_adj;	/* maximum adjustment of hrtime per tick */
161int tick_per_msec;	/* clock ticks per millisecond (zero if hz < 1000) */
162
163/*
164 * Milliseconds, Microseconds, and Nanoseconds per clock tick
165 *
166 * Note:
167 *  msec_per_tick is zero if hz > 1000
168 */
169int msec_per_tick;
170int usec_per_tick;
171int nsec_per_tick;
172
173/*
174 * Time Resolution values. These are defined in condvar.h and initialized in
175 * param_init(). Consumers of cv_reltimedwait() and cv_reltimedwait_sig()
176 * need to specify how accurate the timeout argument should be through
177 * one of these values. The intention is to allow the underlying implementation
178 * to anticipate or defer the expiration of timeouts, preventing unnecessary
179 * wakeups by batch processing similarly expiring events.
180 */
181time_res_t time_res[TR_COUNT];
182
183/*
184 * Setting "snooping" to a non-zero value will cause a deadman panic if
185 * snoop_interval microseconds elapse without lbolt increasing.  The default
186 * snoop_interval is 50 seconds.
187 */
188#define	SNOOP_INTERVAL_MIN	(MICROSEC)
189#define	SNOOP_INTERVAL_DEFAULT	(50 * MICROSEC)
190
191int snooping = 0;
192uint_t snoop_interval = SNOOP_INTERVAL_DEFAULT;
193
194/*
195 * Tables of initialization functions, called from main().
196 */
197
198extern void system_taskq_init(void);
199extern void binit(void);
200extern void space_init(void);
201extern void dnlc_init(void);
202extern void vfsinit(void);
203extern void finit(void);
204extern void strinit(void);
205extern void flk_init(void);
206extern void ftrace_init(void);
207extern void softcall_init(void);
208extern void ttyinit(void);
209extern void schedctl_init(void);
210extern void deadman_init(void);
211extern void clock_timer_init(void);
212extern void clock_realtime_init(void);
213extern void clock_highres_init(void);
214extern void clock_tick_mp_init(void);
215extern void callout_mp_init(void);
216extern void cpu_seq_tbl_init(void);
217
218void	(*init_tbl[])(void) = {
219	system_taskq_init,
220	binit,
221	space_init,
222	dnlc_init,
223	vfsinit,
224	finit,
225	strinit,
226	serializer_init,
227	softcall_init,
228	ttyinit,
229	as_init,
230	pvn_init,
231	anon_init,
232	segvn_init,
233	flk_init,
234	cpu_seq_tbl_init,
235	schedctl_init,
236	fdb_init,
237	deadman_init,
238	clock_timer_init,
239	clock_realtime_init,
240	clock_highres_init,
241	0
242};
243
244
245#if defined(__sparc)
246	extern void siron_mp_init();
247#endif
248
249/*
250 * Any per cpu resources should be initialized via
251 * an entry in mp_init_tbl().
252 */
253void	(*mp_init_tbl[])(void) = {
254	ftrace_init,
255	cyclic_mp_init,
256#if defined(__sparc)
257	siron_mp_init,
258#endif
259	clock_tick_mp_init,
260	callout_mp_init,
261	0
262};
263
264int maxusers;		/* kitchen-sink knob for dynamic configuration */
265
266/*
267 * pidmax -- highest pid value assigned by the system
268 * Settable in /etc/system
269 */
270int pidmax = DEFAULT_MAXPID;
271
272/*
273 * jump_pid - if set, this value is where pid numbers should start
274 * after the first few system pids (0-3) are used.  If 0, pids are
275 * chosen in the usual way. This variable can be used to quickly
276 * create large pids (by setting it to 100000, for example). pids
277 * less than this value will never be chosen.
278 */
279pid_t jump_pid = DEFAULT_JUMPPID;
280
281/*
282 * autoup -- used in struct var for dynamic config of the age a delayed-write
283 * buffer must be in seconds before bdflush will write it out.
284 */
285#define	DEFAULT_AUTOUP	30
286int autoup = DEFAULT_AUTOUP;
287
288/*
289 * bufhwm -- tuneable variable for struct var for v_bufhwm.
290 * high water mark for buffer cache mem usage in units of K bytes.
291 *
292 * bufhwm_pct -- ditto, but given in % of physmem.
293 */
294int bufhwm = 0;
295int bufhwm_pct = 0;
296
297/*
298 * Process table.
299 */
300int maxpid;
301int max_nprocs;		/* set in param_init() */
302int maxuprc;		/* set in param_init() */
303int reserved_procs;
304int nthread = 1;
305
306/*
307 * UFS tunables
308 */
309int ufs_ninode;		/* declared here due to backwards compatibility */
310int ndquot;		/* declared here due to backwards compatibility */
311
312/*
313 * Exec switch table. This is used by the generic exec module
314 * to switch out to the desired executable type, based on the
315 * magic number. The currently supported types are ELF, a.out
316 * (both NMAGIC and ZMAGIC), interpreter (#!) files,
317 * and Java executables.
318 */
319/*
320 * Magic numbers
321 */
322short elfmagic = 0x7f45;
323short intpmagic = 0x2321;
324short jmagic = 0x504b;
325
326#if defined(__sparc)
327short aout_nmagic = NMAGIC;
328short aout_zmagic = ZMAGIC;
329short aout_omagic = OMAGIC;
330#endif
331short nomagic = 0;
332
333/*
334 * Magic strings
335 */
336#define	ELF32MAGIC_STRING	"\x7f""ELF\x1"
337#define	ELF64MAGIC_STRING	"\x7f""ELF\x2"
338#define	INTPMAGIC_STRING	"#!"
339#define	JAVAMAGIC_STRING	"PK\003\004"
340#define	AOUT_OMAGIC_STRING	"\x1""\x07"	/* 0407 */
341#define	AOUT_NMAGIC_STRING	"\x1""\x08"	/* 0410 */
342#define	AOUT_ZMAGIC_STRING	"\x1""\x0b"	/* 0413 */
343#define	NOMAGIC_STRING		""
344
345#define	SHBIN_CNTL(x)	((x)&037)
346#define	SHBINMAGIC_STRING {SHBIN_CNTL('k'), SHBIN_CNTL('s'), SHBIN_CNTL('h'), 0}
347#define	SHBINMAGIC_LEN	4
348
349char elf32magicstr[] = ELF32MAGIC_STRING;
350char elf64magicstr[] = ELF64MAGIC_STRING;
351char intpmagicstr[] = INTPMAGIC_STRING;
352char shbinmagicstr[] = SHBINMAGIC_STRING;
353char javamagicstr[] = JAVAMAGIC_STRING;
354#if defined(__sparc)
355char aout_nmagicstr[] = AOUT_NMAGIC_STRING;
356char aout_zmagicstr[] = AOUT_ZMAGIC_STRING;
357char aout_omagicstr[] = AOUT_OMAGIC_STRING;
358#endif
359char nomagicstr[] = NOMAGIC_STRING;
360
361char *execswnames[] = {
362	"elfexec",	/* Elf32 */
363#ifdef _LP64
364	"elfexec",	/* Elf64 */
365#endif
366	"intpexec",
367	"shbinexec",
368	"javaexec",
369#if defined(__sparc)
370	"aoutexec",
371	"aoutexec",
372	"aoutexec",
373#endif
374	NULL,
375	NULL,
376	NULL
377};
378
379struct execsw execsw[] = {
380	{ elf32magicstr, 0, 5, NULL, NULL, NULL },
381#ifdef _LP64
382	{ elf64magicstr, 0, 5, NULL, NULL, NULL },
383#endif
384	{ intpmagicstr, 0, 2, NULL, NULL, NULL },
385	{ shbinmagicstr, 0, SHBINMAGIC_LEN, NULL, NULL, NULL },
386	{ javamagicstr, 0, 4, NULL, NULL, NULL },
387#if defined(__sparc)
388	{ aout_zmagicstr, 2, 2, NULL, NULL, NULL },
389	{ aout_nmagicstr, 2, 2, NULL, NULL, NULL },
390	{ aout_omagicstr, 2, 2, NULL, NULL, NULL },
391#endif
392	{ nomagicstr, 0, 0, NULL, NULL, NULL },
393	{ nomagicstr, 0, 0, NULL, NULL, NULL },
394	{ nomagicstr, 0, 0, NULL, NULL, NULL },
395	{ nomagicstr, 0, 0, NULL, NULL, NULL }
396};
397int nexectype = sizeof (execsw) / sizeof (execsw[0]);	/* # of exec types */
398kmutex_t execsw_lock;	/* Used for allocation of execsw entries */
399
400/*
401 * symbols added to make changing max-file-descriptors
402 * simple via /etc/system
403 */
404#define	RLIM_FD_CUR 0x100
405#define	RLIM_FD_MAX 0x10000
406
407uint_t rlim_fd_cur = RLIM_FD_CUR;
408uint_t rlim_fd_max = RLIM_FD_MAX;
409
410/*
411 * (Default resource limits were formerly declared here, but are now provided by
412 * the more general resource controls framework.)
413 */
414
415/*
416 * STREAMS tunables
417 */
418int	nstrpush = 9;		/* maximum # of modules/drivers on a stream */
419ssize_t	strctlsz = 1024;	/* maximum size of user-generated M_PROTO */
420ssize_t	strmsgsz = 0x10000;	/* maximum size of user-generated M_DATA */
421				/* for `strmsgsz', zero means unlimited */
422/*
423 * Filesystem tunables
424 */
425int	rstchown = 1;		/* POSIX_CHOWN_RESTRICTED is enabled */
426int	ngroups_max = NGROUPS_MAX_DEFAULT;
427
428/*
429 * generic scheduling stuff
430 *
431 * Configurable parameters for RT and TS are in the respective
432 * scheduling class modules.
433 */
434
435pri_t maxclsyspri = MAXCLSYSPRI;
436pri_t minclsyspri = MINCLSYSPRI;
437char sys_name[] = "SYS";
438
439extern pri_t sys_init();
440extern classfuncs_t sys_classfuncs;
441
442sclass_t sclass[] = {
443	{ "SYS",	sys_init,	&sys_classfuncs, STATIC_SCHED, 0 },
444	{ "",	NULL,	NULL,	NULL, 0 },
445	{ "",	NULL,	NULL,	NULL, 0 },
446	{ "",	NULL,	NULL,	NULL, 0 },
447	{ "",	NULL,	NULL,	NULL, 0 },
448	{ "",	NULL,	NULL,	NULL, 0 },
449	{ "",	NULL,	NULL,	NULL, 0 },
450	{ "",	NULL,	NULL,	NULL, 0 },
451	{ "",	NULL,	NULL,	NULL, 0 },
452	{ "",	NULL,	NULL,	NULL, 0 }
453};
454
455int loaded_classes = 1;		/* for loaded classes */
456kmutex_t class_lock;		/* lock for class[] */
457
458int nclass = sizeof (sclass) / sizeof (sclass_t);
459char initcls[] = "TS";
460char *defaultclass = initcls;
461
462/*
463 * Tunable system parameters.
464 */
465
466/*
467 * The integers tune_* are done this way so that the tune
468 * data structure may be "tuned" if necessary from the /etc/system
469 * file. The tune data structure is initialized in param_init();
470 */
471
472tune_t tune;
473
474/*
475 * If freemem < t_getpgslow, then start to steal pages from processes.
476 */
477int tune_t_gpgslo = 25;
478
479/*
480 * Rate at which fsflush is run, in seconds.
481 */
482#define	DEFAULT_TUNE_T_FSFLUSHR	1
483int tune_t_fsflushr = DEFAULT_TUNE_T_FSFLUSHR;
484
485/*
486 * The minimum available resident (not swappable) memory to maintain
487 * in order to avoid deadlock.  In pages.
488 */
489int tune_t_minarmem = 25;
490
491/*
492 * The minimum available swappable memory to maintain in order to avoid
493 * deadlock.  In pages.
494 */
495int tune_t_minasmem = 25;
496
497int tune_t_flckrec = 512;	/* max # of active frlocks */
498
499/*
500 * Number of currently available pages that cannot be 'locked'
501 * This is set in init_pages_pp_maximum, and must be initialized
502 * to zero here to detect an override in /etc/system
503 */
504pgcnt_t pages_pp_maximum = 0;
505
506int boothowto;			/* boot flags passed to kernel */
507struct var v;			/* System Configuration Information */
508
509/*
510 * System Configuration Information
511 */
512
513/*
514 * The physical system's host identifier, expressed as a decimal string.
515 * Code should only directly access this value when writing to it (setting the
516 * physical system's host identifier).  Code that reads the physical system's
517 * host identifier should use zone_get_hostid(NULL) instead.
518 */
519char hw_serial[HW_HOSTID_LEN] = "0";
520
521#if defined(__sparc)
522
523/*
524 * On sparc machines, read hw_serial from the firmware at boot time
525 * and simply assert Sun is the hardware provider.  Hmm.
526 */
527char architecture[] = "sparcv9";
528char architecture_32[] = "sparc";
529char hw_provider[] = "Sun_Microsystems";
530
531#elif defined(__i386)
532
533/*
534 * On x86 machines, read hw_serial, hw_provider and srpc_domain from
535 * /etc/bootrc at boot time.
536 */
537char architecture[] = "i386";
538char architecture_32[] = "i386";
539char hw_provider[SYS_NMLN] = "";
540
541#elif defined(__amd64)
542
543/*
544 * On amd64 machines, read hw_serial, hw_provider and srpc_domain from
545 * /etc/bootrc at boot time.
546 */
547char architecture[] = "amd64";
548char architecture_32[] = "i386";
549char hw_provider[SYS_NMLN] = "";
550
551#else
552#error "unknown processor architecture"
553#endif
554
555char srpc_domain[SYS_NMLN] = "";
556char platform[SYS_NMLN] = "";	/* read from the devinfo root node */
557
558/* Initialize isa_list */
559char *isa_list = architecture;
560
561static pgcnt_t original_physmem = 0;
562
563#define	MIN_DEFAULT_MAXUSERS	8u
564#define	MAX_DEFAULT_MAXUSERS	2048u
565#define	MAX_MAXUSERS		4096u
566
567void
568param_preset(void)
569{
570	original_physmem = physmem;
571}
572
573void
574param_calc(int platform_max_nprocs)
575{
576	/*
577	 * Default to about one "user" per megabyte, taking into
578	 * account both physical and virtual constraints.
579	 * Note: 2^20 is a meg; shifting right by (20 - PAGESHIFT)
580	 * converts pages to megs without integer overflow.
581	 */
582#if defined(__sparc)
583	if (physmem > original_physmem) {
584		physmem = original_physmem;
585		cmn_err(CE_NOTE, "physmem limited to %ld", physmem);
586	}
587#endif
588	if (maxusers == 0) {
589		pgcnt_t physmegs = physmem >> (20 - PAGESHIFT);
590		pgcnt_t virtmegs = vmem_size(heap_arena, VMEM_FREE) >> 20;
591		maxusers = MIN(MAX(MIN(physmegs, virtmegs),
592		    MIN_DEFAULT_MAXUSERS), MAX_DEFAULT_MAXUSERS);
593	}
594	if (maxusers > MAX_MAXUSERS) {
595		maxusers = MAX_MAXUSERS;
596		cmn_err(CE_NOTE, "maxusers limited to %d", MAX_MAXUSERS);
597	}
598
599	if (ngroups_max > NGROUPS_MAX_DEFAULT)
600		cmn_err(CE_WARN, "ngroups_max of %d > %d, NFS AUTH_SYS will"
601		    " not work properly", ngroups_max, NGROUPS_MAX_DEFAULT);
602
603#ifdef DEBUG
604	/*
605	 * The purpose of maxusers is to prevent memory overcommit.
606	 * DEBUG kernels take more space, so reduce maxusers a bit.
607	 */
608	maxusers = (3 * maxusers) / 4;
609#endif
610
611	/*
612	 * We need to dynamically change any variables now so that
613	 * the setting of maxusers and pidmax propagate to the other
614	 * variables that are dependent on them.
615	 */
616	if (reserved_procs == 0)
617		reserved_procs = 5;
618	if (pidmax < reserved_procs || pidmax > MAX_MAXPID)
619		maxpid = MAX_MAXPID;
620	else
621		maxpid = pidmax;
622
623	/*
624	 * This allows platform-dependent code to constrain the maximum
625	 * number of processes allowed in case there are e.g. VM limitations
626	 * with how many contexts are available.
627	 */
628	if (max_nprocs == 0)
629		max_nprocs = (10 + 16 * maxusers);
630	if (platform_max_nprocs > 0 && max_nprocs > platform_max_nprocs)
631		max_nprocs = platform_max_nprocs;
632	if (max_nprocs > maxpid)
633		max_nprocs = maxpid;
634
635	if (maxuprc == 0)
636		maxuprc = (max_nprocs - reserved_procs);
637}
638
639void
640param_init(void)
641{
642	/*
643	 * Set each individual element of struct var v to be the
644	 * default value. This is done this way
645	 * so that a user can set the assigned integer value in the
646	 * /etc/system file *IF* tuning is needed.
647	 */
648	v.v_proc = max_nprocs;	/* v_proc - max # of processes system wide */
649	v.v_maxupttl = max_nprocs - reserved_procs;
650	v.v_maxsyspri = (int)maxclsyspri;  /* max global pri for sysclass */
651	v.v_maxup = MIN(maxuprc, v.v_maxupttl); /* max procs per user */
652	v.v_autoup = autoup;	/* v_autoup - delay for delayed writes */
653
654	/*
655	 * Set each individual element of struct tune to be the
656	 * default value. Each struct element This is done this way
657	 *  so that a user can set the assigned integer value in the
658	 * /etc/system file *IF* tuning is needed.
659	 */
660	tune.t_gpgslo = tune_t_gpgslo;
661	tune.t_fsflushr = tune_t_fsflushr;
662	tune.t_minarmem = tune_t_minarmem;
663	tune.t_minasmem = tune_t_minasmem;
664	tune.t_flckrec = tune_t_flckrec;
665
666	/*
667	 * Initialization for file descriptors to correct mistaken settings in
668	 * /etc/system.  Initialization of limits performed by resource control
669	 * system.
670	 */
671	if (rlim_fd_cur > rlim_fd_max)
672		rlim_fd_cur = rlim_fd_max;
673
674	/*
675	 * calculations needed if hz was set in /etc/system
676	 */
677	if (hires_tick)
678		hz = hires_hz;
679
680	tick_per_msec = hz / MILLISEC;
681	msec_per_tick = MILLISEC / hz;
682	usec_per_tick = MICROSEC / hz;
683	nsec_per_tick = NANOSEC / hz;
684	max_hres_adj = nsec_per_tick >> ADJ_SHIFT;
685
686	/*
687	 * Consumers of relative timedwait functions must specify how accurately
688	 * the given timeout must expire. This is currently TR_CLOCK_TICK for
689	 * the vast majority of consumers, but nsec_per_tick becomes an
690	 * artificial value in a tickless world. Each caller of such routines
691	 * should re-evaluate their usage and specify the appropriate
692	 * resolution.
693	 */
694	time_res[TR_NANOSEC] = SEC;
695	time_res[TR_MICROSEC] = MILLISEC;
696	time_res[TR_MILLISEC] = MICROSEC;
697	time_res[TR_SEC] = NANOSEC;
698	time_res[TR_CLOCK_TICK] = nsec_per_tick;
699}
700
701/*
702 * Validate tuneable parameters following /etc/system processing,
703 * but prior to param_init().
704 */
705void
706param_check(void)
707{
708#if defined(__x86)
709	if (physmem != original_physmem) {
710		cmn_err(CE_NOTE, "physmem cannot be modified to 0x%lx"
711		    " via /etc/system. Please use eeprom(1M) instead.",
712		    physmem);
713		physmem = original_physmem;
714	}
715#endif
716	if (ngroups_max < NGROUPS_UMIN)
717		ngroups_max = NGROUPS_UMIN;
718	if (ngroups_max > NGROUPS_UMAX)
719		ngroups_max = NGROUPS_UMAX;
720
721	/* If we have many groups then the ucred proto message also grows. */
722	if (ngroups_max > NGROUPS_OLDMAX &&
723	    strctlsz < (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) + 1024) {
724		strctlsz = (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) +
725		    1024;
726	}
727
728	if (autoup <= 0) {
729		autoup = DEFAULT_AUTOUP;
730		cmn_err(CE_WARN, "autoup <= 0; defaulting to %d", autoup);
731	}
732
733	if (tune_t_fsflushr <= 0) {
734		tune_t_fsflushr = DEFAULT_TUNE_T_FSFLUSHR;
735		cmn_err(CE_WARN, "tune_t_fsflushr <= 0; defaulting to %d",
736		    tune_t_fsflushr);
737	}
738
739	if (jump_pid < 0 || jump_pid >= pidmax) {
740		jump_pid = 0;
741		cmn_err(CE_WARN, "jump_pid < 0 or >= pidmax; ignored");
742	}
743
744	if (snoop_interval < SNOOP_INTERVAL_MIN) {
745		snoop_interval = SNOOP_INTERVAL_DEFAULT;
746		cmn_err(CE_WARN, "snoop_interval < minimum (%d); defaulting"
747		    " to %d", SNOOP_INTERVAL_MIN, SNOOP_INTERVAL_DEFAULT);
748	}
749}
750