param.c revision 35b1ab9964f57b69ba8f03d2962f94036aa78c57
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/resource.h>
#include <vm/seg_kmem.h>
#include <sys/machparam.h>
#include <sys/fdbuffer.h>
#include <sys/cyclic_impl.h>
#include <sys/tuneable.h>
#include <sys/serializer.h>
/*
* The following few lines describe generic things that must be compiled
* into the booted executable (unix) rather than genunix or any other
* module because they're required by crash dump readers, etc.
*/
char *default_path; /* default module loading path */
/*
* The following are "implementation architecture" dependent constants made
* available here in the form of initialized data for use by "implementation
* architecture" independent modules. See machparam.h.
*/
const unsigned int _pageshift = (unsigned int)PAGESHIFT;
const unsigned long _pageoffset = (unsigned long)PAGEOFFSET;
/*
* XXX - This value pagemask has to be a 64bit size because
* large file support uses this mask on offsets which are 64 bit size.
* using unsigned leaves the higher 32 bits value as zero thus
* corrupting offset calculations in the file system and VM.
*/
const unsigned long _mmu_pagesize = (unsigned long)MMU_PAGESIZE;
const unsigned int _mmu_pageshift = (unsigned int)MMU_PAGESHIFT;
const unsigned long _mmu_pageoffset = (unsigned long)MMU_PAGEOFFSET;
const unsigned long _mmu_pagemask = (unsigned long)MMU_PAGEMASK;
const unsigned long _maxhandspreadpages = (unsigned long)MAXHANDSPREADPAGES;
const unsigned long _defaultstksz = (unsigned long)DEFAULTSTKSZ;
const unsigned int _nbpg = (unsigned int)MMU_PAGESIZE;
/*
* System parameter formulae.
*
* This file is copied into each directory where we compile
* the kernel; it should be modified there to suit local taste
* if necessary.
*/
/*
* Default hz is 100, but if we set hires_tick we get higher resolution
* clock behavior (currently defined to be 1000 hz). Higher values seem
* to work, but are not supported.
*
* If we do decide to play with higher values, remember that hz should
* satisfy the following constraints to avoid integer round-off problems:
*
* (1) hz should be in the range 100 <= hz <= MICROSEC. If hz exceeds
* MICROSEC, usec_per_tick will be zero and lots of stuff will break.
* Similarly, if hz < 100 then hz / 100 == 0 and stuff will break.
*
* (2) If hz <= 1000, it should be both a multiple of 100 and a
* divisor of 1000.
*
* (3) If hz > 1000, it should be both a multiple of 1000 and a
* divisor of MICROSEC.
*
* Thus the only reasonable values of hz (i.e. the values that won't
* cause roundoff error) are: 100, 200, 500, 1000, 2000, 4000, 5000,
* 8000, 10000, 20000, 25000, 40000, 50000, 100000, 125000, 200000,
* 250000, 500000, 1000000. As of this writing (1996) a clock rate
* of more than about 10 kHz seems utterly ridiculous, although
* this observation will no doubt seem quaintly amusing one day.
*/
int hz = 100;
int hires_hz = 1000;
int hires_tick = 0;
int tick_per_msec; /* clock ticks per millisecond (zero if hz < 1000) */
int msec_per_tick; /* millseconds per clock tick (zero if hz > 1000) */
int usec_per_tick; /* microseconds per clock tick */
int nsec_per_tick; /* nanoseconds per clock tick */
int max_hres_adj; /* maximum adjustment of hrtime per tick */
/*
* Setting "snooping" to a non-zero value will cause a deadman panic if
* snoop_interval microseconds elapse without lbolt increasing. The default
* snoop_interval is 50 seconds.
*/
#define SNOOP_INTERVAL_MIN (MICROSEC)
int snooping = 0;
/*
* Tables of initialization functions, called from main().
*/
extern void system_taskq_init(void);
extern void binit(void);
extern void space_init(void);
extern void dnlc_init(void);
extern void vfsinit(void);
extern void finit(void);
extern void strinit(void);
extern void flk_init(void);
extern void ftrace_init(void);
extern void softcall_init(void);
extern void ttyinit(void);
extern void schedctl_init(void);
extern void deadman_init(void);
extern void clock_timer_init(void);
extern void clock_realtime_init(void);
extern void clock_highres_init(void);
extern void pg_init(void);
extern void pg_cmt_class_init(void);
extern void pg_cpu0_init(void);
void (*init_tbl[])(void) = {
0
};
/*
* Any per cpu resources should be initialized via
* an entry in mp_init_tbl().
*/
void (*mp_init_tbl[])(void) = {
0
};
int maxusers; /* kitchen-sink knob for dynamic configuration */
/*
* pidmax -- highest pid value assigned by the system
*/
int pidmax = DEFAULT_MAXPID;
/*
* jump_pid - if set, this value is where pid numbers should start
* after the first few system pids (0-3) are used. If 0, pids are
* chosen in the usual way. This variable can be used to quickly
* create large pids (by setting it to 100000, for example). pids
* less than this value will never be chosen.
*/
/*
* autoup -- used in struct var for dynamic config of the age a delayed-write
* buffer must be in seconds before bdflush will write it out.
*/
#define DEFAULT_AUTOUP 30
int autoup = DEFAULT_AUTOUP;
/*
* bufhwm -- tuneable variable for struct var for v_bufhwm.
* high water mark for buffer cache mem usage in units of K bytes.
*
* bufhwm_pct -- ditto, but given in % of physmem.
*/
int bufhwm = 0;
int bufhwm_pct = 0;
/*
* Process table.
*/
int maxpid;
int max_nprocs; /* set in param_init() */
int maxuprc; /* set in param_init() */
int reserved_procs;
int nthread = 1;
/*
* UFS tunables
*/
int ufs_ninode; /* declared here due to backwards compatibility */
int ndquot; /* declared here due to backwards compatibility */
/*
* Exec switch table. This is used by the generic exec module
* to switch out to the desired executable type, based on the
* magic number. The currently supported types are ELF, a.out
* (both NMAGIC and ZMAGIC), interpreter (#!) files,
* and Java executables.
*/
/*
* Magic numbers
*/
short elfmagic = 0x7f45;
short intpmagic = 0x2321;
short jmagic = 0x504b;
#if defined(__sparc)
short aout_nmagic = NMAGIC;
short aout_zmagic = ZMAGIC;
short aout_omagic = OMAGIC;
#endif
short nomagic = 0;
/*
* Magic strings
*/
#define INTPMAGIC_STRING "#!"
#define JAVAMAGIC_STRING "PK\003\004"
#define NOMAGIC_STRING ""
char elf32magicstr[] = ELF32MAGIC_STRING;
char elf64magicstr[] = ELF64MAGIC_STRING;
char intpmagicstr[] = INTPMAGIC_STRING;
char javamagicstr[] = JAVAMAGIC_STRING;
#if defined(__sparc)
char aout_nmagicstr[] = AOUT_NMAGIC_STRING;
char aout_zmagicstr[] = AOUT_ZMAGIC_STRING;
char aout_omagicstr[] = AOUT_OMAGIC_STRING;
#endif
char nomagicstr[] = NOMAGIC_STRING;
char *execswnames[] = {
"elfexec", /* Elf32 */
#ifdef _LP64
"elfexec", /* Elf64 */
#endif
"intpexec",
"javaexec",
#if defined(__sparc)
"aoutexec",
"aoutexec",
"aoutexec",
#endif
NULL,
NULL,
};
#ifdef _LP64
#endif
#if defined(__sparc)
#endif
};
/*
* symbols added to make changing max-file-descriptors
*/
#define RLIM_FD_CUR 0x100
#define RLIM_FD_MAX 0x10000
/*
* (Default resource limits were formerly declared here, but are now provided by
* the more general resource controls framework.)
*/
/*
* STREAMS tunables
*/
/* for `strmsgsz', zero means unlimited */
/*
* Filesystem tunables
*/
int ngroups_max = NGROUPS_MAX_DEFAULT;
/*
* generic scheduling stuff
*
* Configurable parameters for RT and TS are in the respective
* scheduling class modules.
*/
char sys_name[] = "SYS";
extern classfuncs_t sys_classfuncs;
};
char initcls[] = "TS";
char *defaultclass = initcls;
/*
* Tunable system parameters.
*/
/*
* The integers tune_* are done this way so that the tune
* file. The tune data structure is initialized in param_init();
*/
/*
* If freemem < t_getpgslow, then start to steal pages from processes.
*/
int tune_t_gpgslo = 25;
/*
* Rate at which fsflush is run, in seconds.
*/
#define DEFAULT_TUNE_T_FSFLUSHR 1
/*
* The minimum available resident (not swappable) memory to maintain
* in order to avoid deadlock. In pages.
*/
int tune_t_minarmem = 25;
/*
* The minimum available swappable memory to maintain in order to avoid
* deadlock. In pages.
*/
int tune_t_minasmem = 25;
/*
* Number of currently available pages that cannot be 'locked'
* This is set in init_pages_pp_maximum, and must be initialized
*/
pgcnt_t pages_pp_maximum = 0;
int boothowto; /* boot flags passed to kernel */
struct var v; /* System Configuration Information */
/*
* System Configuration Information
*/
#if defined(__sparc)
/*
* On sparc machines, read hw_serial from the firmware at boot time
* and simply assert Sun is the hardware provider. Hmm.
*/
char architecture[] = "sparcv9";
char architecture_32[] = "sparc";
char hw_serial[11];
char hw_provider[] = "Sun_Microsystems";
/*
* On x86 machines, read hw_serial, hw_provider and srpc_domain from
*/
char architecture[] = "i386";
char architecture_32[] = "i386";
/*
* On amd64 machines, read hw_serial, hw_provider and srpc_domain from
*/
char architecture[] = "amd64";
char architecture_32[] = "i386";
#else
#error "unknown processor architecture"
#endif
/* Initialize isa_list */
char *isa_list = architecture;
static pgcnt_t original_physmem = 0;
#define MIN_DEFAULT_MAXUSERS 8u
#define MAX_DEFAULT_MAXUSERS 2048u
#define MAX_MAXUSERS 4096u
void
param_preset(void)
{
}
void
{
/*
* Default to about one "user" per megabyte, taking into
* account both physical and virtual constraints.
* Note: 2^20 is a meg; shifting right by (20 - PAGESHIFT)
* converts pages to megs without integer overflow.
*/
#if defined(__sparc)
if (physmem > original_physmem) {
}
#endif
if (maxusers == 0) {
}
if (maxusers > MAX_MAXUSERS) {
}
if (ngroups_max > NGROUPS_MAX_DEFAULT)
#ifdef DEBUG
/*
* The purpose of maxusers is to prevent memory overcommit.
* DEBUG kernels take more space, so reduce maxusers a bit.
*/
#endif
/*
* We need to dynamically change any variables now so that
* the setting of maxusers and pidmax propagate to the other
* variables that are dependent on them.
*/
if (reserved_procs == 0)
reserved_procs = 5;
maxpid = MAX_MAXPID;
else
/*
* This allows platform-dependent code to constrain the maximum
* number of processes allowed in case there are e.g. VM limitations
* with how many contexts are available.
*/
if (max_nprocs == 0)
if (max_nprocs > maxpid)
max_nprocs = maxpid;
if (maxuprc == 0)
}
void
param_init(void)
{
/*
* Set each individual element of struct var v to be the
* default value. This is done this way
* so that a user can set the assigned integer value in the
*/
/*
* Set each individual element of struct tune to be the
* default value. Each struct element This is done this way
* so that a user can set the assigned integer value in the
*/
/*
* Initialization for file descriptors to correct mistaken settings in
* system.
*/
if (rlim_fd_cur > rlim_fd_max)
/*
*/
if (hires_tick)
}
/*
* but prior to param_init().
*/
void
param_check(void)
{
#if defined(__x86)
if (physmem != original_physmem) {
physmem);
}
#endif
if (autoup <= 0) {
}
if (tune_t_fsflushr <= 0) {
}
jump_pid = 0;
}
if (snoop_interval < SNOOP_INTERVAL_MIN) {
}
}