************************************************************************** * Copyright 1990, Silicon Graphics, Inc. * All Rights Reserved. * * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.; * the contents of this file may not be disclosed to third parties, copied or * duplicated in any form, in whole or in part, without the prior written * permission of Silicon Graphics, Inc. * * RESTRICTED RIGHTS LEGEND: * Use, duplication or disclosure by the Government is subject to restrictions * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data * and Computer Software clause at DFARS 252.227-7013, and/or in similar or * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - * rights reserved under the Copyright Laws of the United States. ************************************************************************** * *#ident "$Revision: 3.174 $ * * KERNEL * *FLAG PREFIX SOFT #DEV DEPENDENCIES k - - - $$$ /* kernel: */ #include "sys/types.h" #include "sys/param.h" #include "sys/sysmacros.h" #include "sys/signal.h" #include "sys/termio.h" #include "sys/immu.h" #include "sys/pfdat.h" #include "sys/buf.h" #include "sys/iobuf.h" #include "sys/file.h" #include "sys/inode.h" #include "sys/region.h" #include "sys/reg.h" #include "sys/sbd.h" #include "sys/proc.h" #include "sys/user.h" #include "sys/callo.h" #include "sys/mount.h" #include "sys/map.h" #include "sys/var.h" #include "sys/tuneable.h" #include "sys/fcntl.h" #include "sys/flock.h" #include "sys/fstyp.h" #include "sys/utsname.h" #include "sys/conf.h" #include "sys/fsid.h" #include "sys/nami.h" #include "sys/stream.h" #include "sys/strmp.h" #include "sys/sysinfo.h" #include "sys/ipc.h" #include "sys/shm.h" #include "sys/sem.h" #include "sys/msg.h" #include "sys/log.h" #include "sys/edt.h" #include "sys/dvh.h" #include "sys/elog.h" #include "sys/sema.h" #include "sys/pda.h" #include "sys/splock.h" #include "sys/time.h" #include "sys/resource.h" #include "sys/schedctl.h" #include "./bwhen.h" #define UNAME_SYS "IRIX" #define UNAME_NODE "IRIS" #define UNAME_REL BWHEN_REL #define UNAME_VER BWHEN_VER #if IP4 #define UNAME_MACH "IP4" #endif #if IP5 #define UNAME_MACH "IP5" #endif #if IP6 #define UNAME_MACH "IP6" #endif #if IP12 #define UNAME_MACH "IP12" #endif #if IP17 #define UNAME_MACH "IP17" #endif #if IP20 #define UNAME_MACH "IP20" #endif #ifdef IP22 #define UNAME_MACH "IP22" #endif #if R2300 #define UNAME_MACH "R2300" #endif /* * uname */ struct utsname utsname = { UNAME_SYS, UNAME_NODE, UNAME_REL, UNAME_VER, UNAME_MACH, }; /* * The following entries form the tunable parameter table. */ #define NMOUNT 128 /* # mounts */ #ifndef NPROC #define NPROC 1000 /* # processes */ #endif #define NFILE (5*NPROC+80) /* # open files system wide */ #define NINODE (NMOUNT+NFILE) /* # inodes system wide */ #define NCLIST 0 /* not used by SGI SVR3 */ #define NBUF 0 /* # buffers in disk buffer cache */ /* autoconfigure if 0 */ #define NHBUF 0 /* # hashbuf must be a power of 2 */ /* autoconfigure if 0 */ #define NCALL (NPROC+32) /* # callouts */ #define NDQUOT NINODE #define NPROFIL 100 /* # of disjoint text spaces to be profiled */ /* *The following stuff is for STREAMS. */ #define NBLK4096 6 #define NBLK2048 (2+4) #define NBLK1024 (2+6) #define NBLK512 40 #define NBLK256 64 #define NBLK128 (16+16) #define NBLK64 (32+32) #define NBLK16 384 #define NBLK4 (512+512) #define NMUXLINK 32 #define NSTRPUSH 9 #define NSTREVENT 30 /* initial pool of events */ #define MAXSEPGCNT 3 /* max. additional chunks */ #define STRLOFRAC 80 #define STRMEDFRAC 90 #define STRMSGSZ 4096 #define STRCTLSZ 1024 #define NSTRINTR 1024 /* STREAMS interrupt blocks (for MP only) */ #define NBLKS (NBLK4096+NBLK2048+NBLK1024+NBLK512+NBLK256+NBLK128+NBLK64+NBLK16+NBLK4) #define NMBLOCK (NBLKS + (NBLKS/4)) struct msgb mblock[NMBLOCK]; struct datab dblock[NBLKS]; char dblock_data[NBLK4096*4096+NBLK2048*2048+NBLK1024*1024+NBLK512*512+NBLK256*256+NBLK128*128+NBLK64*64+NBLK16*16+NBLK4*4]; struct linkblk linkblk[NMUXLINK]; int nmuxlink = NMUXLINK; int nstrpush = NSTRPUSH; struct strevent strevent[NSTREVENT]; int nstrevent = NSTREVENT; int maxsepgcnt = MAXSEPGCNT; int strmsgsz = STRMSGSZ; int strctlsz = STRCTLSZ; char strlofrac = STRLOFRAC; char strmedfrac = STRMEDFRAC; int nmblock = NMBLOCK; int nprofile = NPROFIL; #ifdef MP_STREAMS int nstrintr = NSTRINTR; struct strintr strintrblock[NSTRINTR]; #endif #if R4000 && JUMP_WAR /* * Enables a workaround for a bug in early Revisions of the R4000. * This bug exists in at least Rev 2.2 and before. */ /* Attempt to correct jumps at the end of pages. */ int R4000_jump_war_correct = 1; /* Warn the user and log in SYSLOG, if unable to correct */ int R4000_jump_war_warn = 1; /* Kill the process if unable to correct. */ int R4000_jump_war_kill = 1; /* Handle ANY jump/branch at the end of a page as a problem */ int R4000_jump_war_always = 0; #endif /* Setup the miniroot variable for kernel miniroot configuration */ #if ! R4000 int R4000_badva_war = 0; #else int R4000_badva_war = 1; #endif #ifdef MINIROOT u_char miniroot = 1; #else u_char miniroot = 0; #endif /* starting default offset in dumpdev to dump kernel when it crashes */ long dumplo = 0; /* * Per Process Limits */ /* * NGROUPS_MAX (# of multiple groups per user) is configurable on a system * basis; NGROUPS_UMIN <= NGROUPS_MAX <= NGROUPS_UMAX (defined in param.h) * Set this to zero in order to disable multiple groups. */ #define NGROUPS_MAX 16 int ngroups_max = NGROUPS_MAX; /* * Maximum number of open files per process. Now a configurable * parameter but only applies to direct open and close calls (i.e * stdio, sh, etc will not make use of more than 100 in this release). */ #define NOFILES 100 /* * resource limits - defaults - 'cur' may be changed via any shell or setrlimit */ /*#define MAXUMEM btoc(512*1024*1024) /* 512Mb per process */ #define MAXUMEM btoc(50*1024*1024) /* 512Mb per process */ #define DEFRSSSZ 0 /* auto-config */ /*#define DEFRSSSZ (MAXUMEM*NBPP) /* for 3.2 compatibility */ #define DEFSTKSZ (64*1024*1024) struct rlimit defrlimit[RLIM_NLIMITS] = { RLIM_INFINITY, /* cur RLIM_CPU */ RLIM_INFINITY, /* max RLIM_CPU */ CDLIMIT, /* cur RLIM_FSIZE */ CDLIMIT, /* max RLIM_FSIZE */ (MAXUMEM*NBPP), /* cur RLIM_DATA */ (MAXUMEM*NBPP), /* max RLIM_DATA */ DEFSTKSZ, /* cur RLIM_STACK */ (MAXUMEM*NBPP), /* max RLIM_STACK */ CDLIMIT, /* cur RLIM_CORE */ CDLIMIT, /* max RLIM_CORE */ DEFRSSSZ, /* cur RLIM_RSS */ (MAXUMEM*NBPP), /* max RLIM_RSS */ }; /* * ncargs is max # bytes of arguments passed during an exec(2) */ #define SYSNCARGS (10*1024) /* wastes stack space if too large */ int ncargs = SYSNCARGS; /* * maxup is the maximum number of processes per user */ #define MAXUP 30 /* * File region locking */ #define FLCKREC NPROC struct flckinfo flckinfo = { FLCKREC, 0, 0, 0, }; struct filock flox[FLCKREC]; /* * Shared Libraries: Maximum number of libraries that can be * attached to a process at one time. */ #define SHLBMAX 8 struct shlbinfo shlbinfo = { SHLBMAX, 0, 0, }; /* * to allow setuid shells set to 0 */ int nosuidshells = 1; /* * maximum watchpoints per process */ int maxwatchpoints = 100; /* * restricted_chown * 1 ==> bsd style chown(2), only super-user can give away files * 0 ==> sysV style chown(2), ie non super-user can give away files */ int restricted_chown = 1; /* * truncatenames = 1 ==> pathname components of > MAXNAMLEN are truncated * truncatenames = 0 ==> pathname components of > MAXNAMLEN return ENAMETOOLONG */ int truncatenames = 0; /* * shortrdwr = 1 ==> kernel returns short reads/writes if interrupted by sig * shortrdwr = 0 ==> kernel returns -1 and EINTR if interrupted */ int shortrdwr = 1; /* * resetclocal = 1 ==> CLOCAL on ttyd* can be reset; POSIX compliant. * resetclocal = 0 ==> CLOCAL is read only. */ int resettable_clocal = 0; /* * preallocation of swap space * 0 ==> disk space not preallocated for processes; * !0 ==> disk space preallocated on fork/exec/sbrk/etc. */ int availsmem_accounting = 0; /* * Delay for delayed writes */ #define NAUTOUP 10 /* * added for paging */ #define NFPREGION 35 /* free pregion pool */ #define NFREGION 25 /* free region pool */ #ifndef MAXPMEM #define MAXPMEM 0 /* auto-config */ #endif #define GPGSLO 0 /* auto-config */ #define GPGSHI 0 /* auto-config */ #if JUMP_WAR /* * Part of the JUMP_WAR fix. */ #define GPGSMSK 0 #else #define GPGSMSK 4 #endif #define MAXDC 100 #define MAXSC 100 #define MAXFC 100 #define BDFLUSHR 5 #define MINARMEM 0 /* auto-config */ #define MINASMEM 0 /* auto-config */ #define MAXLKMEM 2000 /* # pages of lockable memory */ #define TLBFLUSH HZ #if R4000 #define SYSSEGSZ 8192 /* max pages of dynamic system memory */ #else #define SYSSEGSZ 4096 /* max pages of dynamic system memory */ #endif #define MAXDMASZ 1024 /* max dma transfer (in pages) */ /* MUST be less than SYSSEGSZ and */ /* less than the total amount of memory */ #define RSSHOGFRAC 75 /* % of memory RSS hogs can use before being throttled*/ #define RSSHOGSLOP 20 /* # pages of allowable excess of RSS before delay */ #define DWPUSH 0 /* # of logical delwri pushes in one pdflush/updatefs */ /* autoconfig == # of buffers iff 0 */ #if defined(IP12) || defined(IP17) || defined(IP20) || defined(IP22) /* push up to 256 KB per disk request on faster systems by default */ #define DWCLUSTER 64 /* max # of pages to cluster in one delwri push */ #else #define DWCLUSTER 16 /* max # of pages to cluster in one delwri push */ #endif /* console buffer sizes */ #ifndef PUTBUFSZ #define PUTBUFSZ 1024 #endif #define CONBUFSZ 1024 extern binit(), inoinit(), fsinit(), finit(), iinit(), flckinit(), strinit(), bsd_init(), debuginit(), siginit(), procinit(), startup(), devinit(), clkstart(), schedinit(), pgrpinit(), dma_mapinit(), cinit(), cacheinit(); extern void init_malloc(); #if !defined(IP20) && !defined(IP22) extern vme_init(); #endif #ifdef IP22 extern eisa_init(); #endif #ifndef R2300 extern scsi_init(); #endif /* * early system init - before any I/O is performed * interrupts are off for these (but could be handled) */ int (*einit_tbl[])() = { (int (*)()) init_malloc, /* kernel dynamic memory allocator */ dma_mapinit, /* initialize DMA maps */ #if !defined(IP20) && !defined(IP22) vme_init, /* vme ACK init - BEFORE spl lowers */ #endif #ifdef IP22 eisa_init, /* init eisa interface */ #endif #ifndef R2300 scsi_init, /* to quiet interrupts before enabled */ #endif (int (*)()) reg2init, /* re-init reg/vm sema metering */ startup, /* file table stuff */ procinit, /* proc table handling */ pgrpinit, /* process group hash chain handling */ clkstart, /* start clocks */ schedinit, /* scheduler initialization */ cacheinit, /* cacheflush system call init */ 0, }; /* * system init after devices have been probed and initted */ int (*init_tbl[])() = { devinit, /* process config info */ siginit, /* ptrace init */ binit, /* buffer cache */ cinit, /* chunkio init */ inoinit, /* inode cache */ fsinit, /* init file systems */ finit, /* file table */ iinit, /* read in root */ flckinit, /* file locking */ strinit, /* streams */ bsd_init, /* bsd networking.. */ 0 }; /* * File system cache tuneable structures. */ struct buf *buf; struct hbuf *hbuf; /* * Time trimming * The clock is adjusted by this signed number of nanoseconds every * second. * It is limited to 3 milliseconds or 0.3% in clock.c. * Timed(1M) and timeslave(1M) put suggested values in /usr/adm/SYSLOG. */ long timetrim = 0; struct file file[NFILE]; struct inode inode[NINODE]; struct proc proc[NPROC]; struct mount mount[NMOUNT]; char conbuf[CONBUFSZ]; int conbufsz = CONBUFSZ; char putbuf[PUTBUFSZ]; int putbufsz = PUTBUFSZ; /* * dquot - start of the in core quota structures */ struct dquot *dquot; /* maximum # cpus */ #if IP5 #define MAXCPU 8 #else #define MAXCPU 1 #endif int maxcpus = MAXCPU; /* processor-dependent data area */ pdaindr_t pdaindr[MAXCPU]; /* tlb pid owned by each process on each processor */ unsigned char tlbpids[NPROC * MAXCPU]; /* last tlbpid assigned for each processor */ unsigned char cur_tlbpid[MAXCPU]; /* flag indicate that delay calibration has been done on this processor */ int calibrated[MAXCPU]; /* max pass per cpu in clean_xcache before preemption is allowed */ int cachepass[MAXCPU]; /* cpu speed */ int cpufreq[MAXCPU]; struct callout callout[NCALL]; short ncallout = NCALL; /* # of the beasties */ struct callout calltodo[MAXCPU]; unsigned prfstat; /* state of profiler, locore.s needs this */ #if defined(IP12) || defined(IP17) || defined(IP20) || defined(IP22) #define FASTHZ 1000 #else #define FASTHZ 1200 #endif int fastclock = 0; /* enable fast clock */ int fastimer_enable = 0; /* enable fast timer */ int fasthz = FASTHZ; /* profiling/fast itimer clock speed */ struct var v = { NBUF, NCALL, NINODE, (char *)(inode+NINODE), NFILE, (char *)(file+NFILE), NMOUNT, (char *)(mount+NMOUNT), NPROC, (char *)(proc+NPROC), NFPREGION, NFREGION, NCLIST, MAXUP, NHBUF, NHBUF-1, SYSSEGSZ, MAXPMEM, MAXDMASZ, NOFILES, 0, 0, NBLK4096, NBLK2048, NBLK1024, NBLK512, NBLK256, NBLK128, NBLK64, NBLK16, NBLK4, CDLIMIT, NDQUOT, 0 }; struct tune tune = { GPGSLO, GPGSHI, GPGSMSK, MAXSC, MAXFC, MAXDC, MAXUMEM, BDFLUSHR, MINARMEM, MINASMEM, MAXLKMEM, TLBFLUSH, RSSHOGFRAC, RSSHOGSLOP, DWPUSH, DWCLUSTER, NAUTOUP, }; /* * This symbol is defined for kernel namelist searching tools. Using * this symbol, the program can lookup up "kernel_magic" and "end", and * make sure that the value stored at "kernel_magic" equals the namelist * value of "end". If they don't agree then the namelist being scanned * doesn't match /dev/kmem. */ extern long end; long *kernel_magic = &end; /* * master interrupt stack * WARNING: cannot make instacksize larger for MP case unless * in cboot can get contiguous physical pages!!!!!! */ #define INTSTACKSIZE 4096 int intstacksize = INTSTACKSIZE; char intstack[INTSTACKSIZE] = 0; /* in .data so can ref it pronto */ char *eintstack = &intstack[INTSTACKSIZE-EF_SIZE]; /* cpu actions */ #define NOTHER_ACTIONS 40 #define NCACHE_ACTIONS 20 #define NACTIONS (NOTHER_ACTIONS+NCACHE_ACTIONS) action_t actionlist[NACTIONS]; int ncache_actions = NCACHE_ACTIONS; int nactions = NACTIONS; /* spinlock stuff */ /* * Number of spinlocks allocatable to kernel and drivers. * Must be <= SPLOCK_MAX (see sys/splock.h). * For other defines, see individual lock type master files */ #define NSPLOCK 16384 int nsplock = NSPLOCK; int splocktype; int splockmeter = SPLOCKMETER; #if SPLOCKMETER == 0 struct k_splockmeter k_splockmeter[1]; /* has to be defined *sigh* */ #else struct k_splockmeter k_splockmeter[NSPLOCK]; #endif /* semaphore history/metering */ #define MAXSEMAHIST 0 /* # of history records kept */ semahist_t semahist[MAXSEMAHIST+1];/* array of history records */ uint histmax = MAXSEMAHIST; /* maximum entries before wrap */ uint defaultsemameter = DEFAULTSEMAMETER; /* if 1 then by default allocate * a history struct per sema */ /* * if set then 10 ms itimer request is queued on the clock processor * instead of the runing processor . * If a process does a setitimer then uses gettimeofday() to compare the * accuracy of the itimer delivery then itimer_on_clkcpu should be set. * If on the otherhand, itimer request is used to implement a user frequency * based scheduler then itimer_on_clkcpu should be 0. */ int itimer_on_clkcpu; /* VME/SCSI DMA mapping register maps locks */ lock_t dmamaplock; sema_t dmamapout; /* * Defining references for scheduler data structures */ struct sched_disc sdisc[NDISCIPLINES]; /* * table to convert from major# to SCSI ctlr # */ char scsimajor[128] = { /*0*/ 255, /*1*/ 255, /*2*/ 255, /*3*/ 255, /*4*/ 255, /*5*/ 255, /*6*/ 255, /*7*/ 255, /*8*/ 255, /*9*/ 255, /*10*/ 255, /*11*/ 255, /*12*/ 255, /*13*/ 255, /*14*/ 255, /*15*/ 255, /*16*/ 255, /*17*/ 255, /*18*/ 255, /*19*/ 255, /*20*/ 255, /*21*/ 255, /*22*/ 0, /* dksc0 */ /*23*/ 0, /* tpsc0 */ /*24*/ 255, /*25*/ 255, /*26*/ 255, /*27*/ 1, /* dksc1 */ /*28*/ 1, /* tpsc1 */ /*29*/ 1, /* smfd1 */ /*30*/ 255, /*31*/ 255, /*32*/ 255, /*33*/ 255, /*34*/ 255, /*35*/ 255, /*36*/ 255, /*37*/ 255, /*38*/ 255, /*39*/ 255, /*40*/ 0, /* smfd0 */ /*41*/ 255, /*42*/ 255, /*43*/ 255, /*44*/ 255, /*45*/ 255, /*46*/ 255, /*47*/ 255, /*48*/ 255, /*49*/ 255, /*50*/ 255, /*51*/ 255, /*52*/ 255, /*53*/ 255, /*54*/ 255, /*55*/ 255, /*56*/ 255, /*57*/ 255, /*58*/ 255, /*59*/ 255, /*60*/ 255, /*61*/ 255, /*62*/ 255, /*63*/ 255, /*64*/ 255, /*65*/ 255, /*66*/ 255, /*67*/ 255, /*68*/ 255, /*69*/ 255, /*70*/ 255, /*71*/ 255, /*72*/ 255, /*73*/ 255, /*74*/ 255, /*75*/ 255, /*76*/ 255, /*77*/ 255, /*78*/ 255, /*79*/ 255, /*80*/ 255, /*81*/ 2, /* dksc2 */ /*82*/ 3, /* dksc3 */ /*83*/ 2, /* tpsc2 */ /*84*/ 3, /* dksc3 */ /*85*/ 2, /* smfd2 */ /*86*/ 3, /* smfd3 */ /*87*/ 255, /*88*/ 255, /*89*/ 255, /*90*/ 255, /*91*/ 255, /*92*/ 255, /*93*/ 255, /*94*/ 255, /*95*/ 255, /*96*/ 255, /*97*/ 255, /*98*/ 255, /*99*/ 255, /*100*/ 255, /*101*/ 255, /*102*/ 255, /*103*/ 255, /*104*/ 255, /*105*/ 255, /*106*/ 255, /*107*/ 255, /*108*/ 255, /*109*/ 255, /*110*/ 255, /*111*/ 255, /*112*/ 255, /*113*/ 255, /*114*/ 255, /*115*/ 255, /*116*/ 255, /*117*/ 255, /*118*/ 255, /*119*/ 255, /*120*/ 255, /*121*/ 255, /*122*/ 255, /*123*/ 255, /*124*/ 255, /*125*/ 255, /*126*/ 255, /*127*/ 255 }; /* * Initialized in main */ struct sched_cpu scpu[MAXCPU]; /* For debugging to force struct decls into symtab */ static user_t *d_user_t; static shaddr_t *d_shaddr_t; static proc_t *d_proc_t; static reg_t *d_reg_t; static preg_t *d_preg_t; static mreg_t *d_mreg_t; static pfd_t *d_pfd_t; static plist_t *d_plist_t; static phead_t *d_phead_t; static struct lockmap *d_lckmap_t; static pde_t *d_pde_t; static seg_t *d_seg_t; static struct eframe_s *d_eframe_t; static iobuf_t *d_iobuf_t; static mblk_t d_mblk_t; static dblk_t *d_dblk_t; static queue_t *d_queue_t; static struct module_info *d_module_info_t; static struct qinit *d_qinit_t; static struct streamtab *d_streamtab_t; static struct stdata *d_stdata_t; static struct linkblk *d_linkblk_t; static struct strevent *d_strevent_t; static struct dbalcst *d_dbalcst_t; static struct iocblk *d_iocblk_t; static struct stroptions *d_stroptions_t; static struct pathname *d_pathname_t; static struct argnamei *d_argnamei_t; static struct argnotify *d_argnotify_t; static struct nx *d_nx_t;