121585Sdist /* 236580Sbostic * Copyright (c) 1980 The Regents of the University of California. 336580Sbostic * All rights reserved. 436580Sbostic * 536580Sbostic * Redistribution and use in source and binary forms are permitted 636580Sbostic * provided that the above copyright notice and this paragraph are 736580Sbostic * duplicated in all such forms and that any documentation, 836580Sbostic * advertising materials, and other materials related to such 936580Sbostic * distribution and use acknowledge that the software was developed 1036580Sbostic * by the University of California, Berkeley. The name of the 1136580Sbostic * University may not be used to endorse or promote products derived 1236580Sbostic * from this software without specific prior written permission. 1336580Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436580Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536580Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621585Sdist */ 1721585Sdist 1810826Ssam #ifndef lint 1921585Sdist char copyright[] = 2036580Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 2121585Sdist All rights reserved.\n"; 2236580Sbostic #endif /* not lint */ 2310826Ssam 2421585Sdist #ifndef lint 25*38262Smckusick static char sccsid[] = "@(#)vmstat.c 5.14 (Berkeley) 06/08/89"; 2636580Sbostic #endif /* not lint */ 2721585Sdist 281155Sbill #include <sys/param.h> 2918761Ssam #include <sys/file.h> 301155Sbill #include <sys/vm.h> 3129664Ssam #include <sys/dkstat.h> 323162Stoy #include <sys/buf.h> 3315807Smckusick #include <sys/dir.h> 3418761Ssam #include <sys/inode.h> 3517262Smckusick #include <sys/namei.h> 3625708Ssam #include <sys/text.h> 3733610Smckusick #include <sys/malloc.h> 3837912Sbostic #include <stdio.h> 3937912Sbostic #include <ctype.h> 4037912Sbostic #include <nlist.h> 4137912Sbostic #include <paths.h> 421155Sbill 431155Sbill struct nlist nl[] = { 441448Sbill #define X_CPTIME 0 451448Sbill { "_cp_time" }, 461448Sbill #define X_RATE 1 471155Sbill { "_rate" }, 481448Sbill #define X_TOTAL 2 491155Sbill { "_total" }, 501448Sbill #define X_DEFICIT 3 511155Sbill { "_deficit" }, 521448Sbill #define X_FORKSTAT 4 531155Sbill { "_forkstat" }, 541448Sbill #define X_SUM 5 551155Sbill { "_sum" }, 561448Sbill #define X_FIRSTFREE 6 571155Sbill { "_firstfree" }, 581448Sbill #define X_MAXFREE 7 591155Sbill { "_maxfree" }, 609249Ssam #define X_BOOTTIME 8 619249Ssam { "_boottime" }, 621448Sbill #define X_DKXFER 9 631448Sbill { "_dk_xfer" }, 6410826Ssam #define X_REC 10 651155Sbill { "_rectime" }, 6610826Ssam #define X_PGIN 11 671155Sbill { "_pgintime" }, 6810826Ssam #define X_HZ 12 693162Stoy { "_hz" }, 7018761Ssam #define X_PHZ 13 7115266Ssam { "_phz" }, 7215807Smckusick #define X_NCHSTATS 14 7315807Smckusick { "_nchstats" }, 7417262Smckusick #define X_INTRNAMES 15 7517262Smckusick { "_intrnames" }, 7617262Smckusick #define X_EINTRNAMES 16 7717262Smckusick { "_eintrnames" }, 7817262Smckusick #define X_INTRCNT 17 7917262Smckusick { "_intrcnt" }, 8017262Smckusick #define X_EINTRCNT 18 8117262Smckusick { "_eintrcnt" }, 8218761Ssam #define X_DK_NDRIVE 19 8318761Ssam { "_dk_ndrive" }, 8425512Ssam #define X_XSTATS 20 8525512Ssam { "_xstats" }, 8633610Smckusick #define X_KMEMSTAT 21 8733610Smckusick { "_kmemstats" }, 8833610Smckusick #define X_KMEMBUCKETS 22 8933610Smckusick { "_bucket" }, 9010826Ssam #ifdef vax 9125708Ssam #define X_MBDINIT (X_XSTATS+1) 9210826Ssam { "_mbdinit" }, 9325708Ssam #define X_UBDINIT (X_XSTATS+2) 9410826Ssam { "_ubdinit" }, 9510826Ssam #endif 9625708Ssam #ifdef tahoe 9725708Ssam #define X_VBDINIT (X_XSTATS+1) 9825708Ssam { "_vbdinit" }, 9925960Ssam #define X_CKEYSTATS (X_XSTATS+2) 10025960Ssam { "_ckeystats" }, 10125960Ssam #define X_DKEYSTATS (X_XSTATS+3) 10225960Ssam { "_dkeystats" }, 10325708Ssam #endif 10410826Ssam { "" }, 1051155Sbill }; 1061155Sbill 10718761Ssam char **dr_name; 10818761Ssam int *dr_select; 10918761Ssam int dk_ndrive; 11018761Ssam int ndrives = 0; 11118761Ssam #ifdef vax 11218761Ssam char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; 11318761Ssam #else 11418761Ssam char *defdrives[] = { 0 }; 11518761Ssam #endif 1161155Sbill double stat1(); 1171155Sbill int firstfree, maxfree; 1183162Stoy int hz; 11915266Ssam int phz; 12015266Ssam int HZ; 12118761Ssam 12218761Ssam struct { 1231155Sbill int busy; 1241448Sbill long time[CPUSTATES]; 12518761Ssam long *xfer; 1261155Sbill struct vmmeter Rate; 1271155Sbill struct vmtotal Total; 1281155Sbill struct vmmeter Sum; 1291155Sbill struct forkstat Forkstat; 1301155Sbill unsigned rectime; 1311155Sbill unsigned pgintime; 1321155Sbill } s, s1, z; 1331155Sbill #define rate s.Rate 1341155Sbill #define total s.Total 1351155Sbill #define sum s.Sum 1361155Sbill #define forkstat s.Forkstat 1371155Sbill 13810826Ssam struct vmmeter osum; 1391155Sbill int deficit; 1401155Sbill double etime; 1411155Sbill int mf; 14217262Smckusick time_t now, boottime; 14317262Smckusick int printhdr(); 14418768Ssam int lines = 1; 1451155Sbill 14629664Ssam #define INTS(x) ((x) - (hz + phz)) 14729664Ssam 1481155Sbill main(argc, argv) 14910826Ssam int argc; 15010826Ssam char **argv; 1511155Sbill { 1521155Sbill extern char *ctime(); 15329664Ssam register i; 15417262Smckusick int iter, nintv, iflag = 0; 1551155Sbill long t; 15629664Ssam char *arg, **cp, buf[BUFSIZ]; 1571155Sbill 15837912Sbostic nlist(_PATH_UNIX, nl); 1591155Sbill if(nl[0].n_type == 0) { 16037912Sbostic fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX); 1611155Sbill exit(1); 1621155Sbill } 16337912Sbostic mf = open(_PATH_KMEM, 0); 1641155Sbill if(mf < 0) { 16537912Sbostic fprintf(stderr, "vmstat: cannot open %s\n", _PATH_KMEM); 1661155Sbill exit(1); 1671155Sbill } 1681155Sbill iter = 0; 1691155Sbill argc--, argv++; 1701155Sbill while (argc>0 && argv[0][0]=='-') { 1711155Sbill char *cp = *argv++; 1721155Sbill argc--; 1731155Sbill while (*++cp) switch (*cp) { 1741155Sbill 1751155Sbill case 't': 1761155Sbill dotimes(); 1771155Sbill exit(0); 17810826Ssam 1791155Sbill case 'z': 1801155Sbill close(mf); 18137912Sbostic mf = open(_PATH_KMEM, 2); 18218761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 1831155Sbill write(mf, &z.Sum, sizeof z.Sum); 1841155Sbill exit(0); 1851155Sbill 1861155Sbill case 'f': 1871155Sbill doforkst(); 1881155Sbill exit(0); 1891155Sbill 19033610Smckusick case 'm': 19133610Smckusick domem(); 19233610Smckusick exit(0); 19333610Smckusick 1941155Sbill case 's': 1951155Sbill dosum(); 1961155Sbill exit(0); 1971155Sbill 19817262Smckusick case 'i': 19917262Smckusick iflag++; 20017262Smckusick break; 20117262Smckusick 2021155Sbill default: 20318761Ssam fprintf(stderr, 20433610Smckusick "usage: vmstat [ -fsim ] [ interval ] [ count]\n"); 2051155Sbill exit(1); 2061155Sbill } 2071155Sbill } 20818761Ssam lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET); 2091155Sbill read(mf, &firstfree, sizeof firstfree); 21018761Ssam lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET); 2111155Sbill read(mf, &maxfree, sizeof maxfree); 21218761Ssam lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET); 2139249Ssam read(mf, &boottime, sizeof boottime); 21418761Ssam lseek(mf, (long)nl[X_HZ].n_value, L_SET); 2153162Stoy read(mf, &hz, sizeof hz); 21618761Ssam if (nl[X_PHZ].n_value != 0) { 21718761Ssam lseek(mf, (long)nl[X_PHZ].n_value, L_SET); 21818761Ssam read(mf, &phz, sizeof phz); 21918761Ssam } 22015266Ssam HZ = phz ? phz : hz; 22130266Sbostic if (nl[X_DK_NDRIVE].n_value == 0) { 22229664Ssam fprintf(stderr, "dk_ndrive undefined in system\n"); 22318761Ssam exit(1); 2243162Stoy } 22518761Ssam lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET); 22618761Ssam read(mf, &dk_ndrive, sizeof (dk_ndrive)); 22718761Ssam if (dk_ndrive <= 0) { 22829664Ssam fprintf(stderr, "dk_ndrive %d\n", dk_ndrive); 22918761Ssam exit(1); 23018761Ssam } 23118761Ssam dr_select = (int *)calloc(dk_ndrive, sizeof (int)); 23218761Ssam dr_name = (char **)calloc(dk_ndrive, sizeof (char *)); 23318761Ssam #define allocate(e, t) \ 23418761Ssam s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 23518761Ssam s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); 23618761Ssam allocate(xfer, long); 23718761Ssam for (arg = buf, i = 0; i < dk_ndrive; i++) { 23818761Ssam dr_name[i] = arg; 23918761Ssam sprintf(dr_name[i], "dk%d", i); 24018761Ssam arg += strlen(dr_name[i]) + 1; 24118761Ssam } 2423162Stoy read_names(); 2431155Sbill time(&now); 2449249Ssam nintv = now - boottime; 2451155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 24629664Ssam fprintf(stderr, 24729664Ssam "Time makes no sense... namelist must be wrong.\n"); 2481155Sbill exit(1); 2491155Sbill } 25017262Smckusick if (iflag) { 25117262Smckusick dointr(nintv); 25217262Smckusick exit(0); 25317262Smckusick } 25418761Ssam /* 25518761Ssam * Choose drives to be displayed. Priority 25618761Ssam * goes to (in order) drives supplied as arguments, 25718761Ssam * default drives. If everything isn't filled 25818761Ssam * in and there are drives not taken care of, 25918761Ssam * display the first few that fit. 26018761Ssam */ 26118761Ssam ndrives = 0; 26218761Ssam while (argc > 0 && !isdigit(argv[0][0])) { 26318761Ssam for (i = 0; i < dk_ndrive; i++) { 26418761Ssam if (strcmp(dr_name[i], argv[0])) 26518761Ssam continue; 26618761Ssam dr_select[i] = 1; 26718761Ssam ndrives++; 26818761Ssam } 26918761Ssam argc--, argv++; 27018761Ssam } 27118761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 27218761Ssam if (dr_select[i]) 27318761Ssam continue; 27418761Ssam for (cp = defdrives; *cp; cp++) 27518761Ssam if (strcmp(dr_name[i], *cp) == 0) { 27618761Ssam dr_select[i] = 1; 27718761Ssam ndrives++; 27818761Ssam break; 27918761Ssam } 28018761Ssam } 28118761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 28218761Ssam if (dr_select[i]) 28318761Ssam continue; 28418761Ssam dr_select[i] = 1; 28518761Ssam ndrives++; 28618761Ssam } 28718761Ssam if (argc > 1) 28818761Ssam iter = atoi(argv[1]); 28917262Smckusick signal(SIGCONT, printhdr); 2901155Sbill loop: 29118768Ssam if (--lines == 0) 29218768Ssam printhdr(); 29318761Ssam lseek(mf, (long)nl[X_CPTIME].n_value, L_SET); 2941448Sbill read(mf, s.time, sizeof s.time); 29518761Ssam lseek(mf, (long)nl[X_DKXFER].n_value, L_SET); 29618761Ssam read(mf, s.xfer, dk_ndrive * sizeof (long)); 29718761Ssam if (nintv != 1) 29818761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 29918761Ssam else 30018761Ssam lseek(mf, (long)nl[X_RATE].n_value, L_SET); 30118761Ssam read(mf, &rate, sizeof rate); 30218761Ssam lseek(mf, (long)nl[X_TOTAL].n_value, L_SET); 3031155Sbill read(mf, &total, sizeof total); 30410826Ssam osum = sum; 30518761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 30610826Ssam read(mf, &sum, sizeof sum); 30718761Ssam lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET); 3081155Sbill read(mf, &deficit, sizeof deficit); 3091448Sbill etime = 0; 31018761Ssam for (i=0; i < dk_ndrive; i++) { 3111448Sbill t = s.xfer[i]; 3121448Sbill s.xfer[i] -= s1.xfer[i]; 3131448Sbill s1.xfer[i] = t; 3141155Sbill } 3151155Sbill for (i=0; i < CPUSTATES; i++) { 3161448Sbill t = s.time[i]; 3171448Sbill s.time[i] -= s1.time[i]; 3181448Sbill s1.time[i] = t; 3191448Sbill etime += s.time[i]; 3201155Sbill } 3211155Sbill if(etime == 0.) 3221155Sbill etime = 1.; 3233162Stoy printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); 32410826Ssam #define pgtok(a) ((a)*NBPG/1024) 32529664Ssam printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free)); 32615266Ssam printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 32715266Ssam (rate.v_xsfrec+rate.v_xifrec)/nintv); 32810826Ssam printf("%4d", pgtok(rate.v_pgpgin)/nintv); 32910826Ssam printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv, 33010826Ssam pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv); 33118761Ssam etime /= (float)HZ; 33218761Ssam for (i = 0; i < dk_ndrive; i++) 33318761Ssam if (dr_select[i]) 33418761Ssam stats(i); 33515266Ssam printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv, 33615266Ssam rate.v_swtch/nintv); 3371155Sbill for(i=0; i<CPUSTATES; i++) { 3381155Sbill float f = stat1(i); 3391155Sbill if (i == 0) { /* US+NI */ 3401155Sbill i++; 3411155Sbill f += stat1(i); 3421155Sbill } 3431155Sbill printf("%3.0f", f); 3441155Sbill } 3451155Sbill printf("\n"); 3461155Sbill fflush(stdout); 3471155Sbill nintv = 1; 34818768Ssam if (--iter &&argc > 0) { 3491155Sbill sleep(atoi(argv[0])); 3501155Sbill goto loop; 3511155Sbill } 3521155Sbill } 3531155Sbill 35417262Smckusick printhdr() 35517262Smckusick { 35618761Ssam register int i, j; 35718761Ssam 35829664Ssam printf(" procs memory page "); 35918761Ssam i = (ndrives * 3 - 6) / 2; 36018761Ssam if (i < 0) 36118761Ssam i = 0; 36218761Ssam for (j = 0; j < i; j++) 36318761Ssam putchar(' '); 36418761Ssam printf("faults"); 36518761Ssam i = ndrives * 3 - 6 - i; 36618761Ssam for (j = 0; j < i; j++) 36718761Ssam putchar(' '); 36818761Ssam printf(" cpu\n"); 36929664Ssam printf(" r b w avm fre re at pi po fr de sr "); 37018761Ssam for (i = 0; i < dk_ndrive; i++) 37118761Ssam if (dr_select[i]) 37218761Ssam printf("%c%c ", dr_name[i][0], dr_name[i][2]); 37318761Ssam printf(" in sy cs us sy id\n"); 37418768Ssam lines = 19; 37517262Smckusick } 37617262Smckusick 3771155Sbill dotimes() 3781155Sbill { 3791155Sbill 38018761Ssam lseek(mf, (long)nl[X_REC].n_value, L_SET); 3811155Sbill read(mf, &s.rectime, sizeof s.rectime); 38218761Ssam lseek(mf, (long)nl[X_PGIN].n_value, L_SET); 3831155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 38418761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3851155Sbill read(mf, &sum, sizeof sum); 3861155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 3871155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 3881155Sbill printf("\n"); 3891155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 3901155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 3911155Sbill } 3921155Sbill 39330069Ssam #if defined(tahoe) 39430069Ssam #include <tahoe/cpu.h> 39530069Ssam #endif 39630069Ssam 3971155Sbill dosum() 3981155Sbill { 39918761Ssam struct nchstats nchstats; 40025960Ssam struct xstats xstats; 40115807Smckusick long nchtotal; 40225960Ssam #if defined(tahoe) 40325960Ssam struct keystats keystats; 40425960Ssam #endif 4051155Sbill 40618761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 4071155Sbill read(mf, &sum, sizeof sum); 4081155Sbill printf("%9d swap ins\n", sum.v_swpin); 4091155Sbill printf("%9d swap outs\n", sum.v_swpout); 4101155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 4111155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 4121155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 4131155Sbill printf("%9d page ins\n", sum.v_pgin); 4141155Sbill printf("%9d page outs\n", sum.v_pgout); 4153612Sroot printf("%9d pages paged in\n", sum.v_pgpgin); 4163612Sroot printf("%9d pages paged out\n", sum.v_pgpgout); 4173612Sroot printf("%9d sequential process pages freed\n", sum.v_seqfree); 41812830Ssam printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec, 41929664Ssam pct(sum.v_fastpgrec, sum.v_pgrec)); 4201155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 4211155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 4221155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 4231155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 4241155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 4251155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 4261155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 4271155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 4281155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 4291155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 4301155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 4311155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 4321155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 4331155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 4341155Sbill printf("%9d device interrupts\n", sum.v_intr); 43517262Smckusick printf("%9d software interrupts\n", sum.v_soft); 43618761Ssam #ifdef vax 43724429Smckusick printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma); 43818761Ssam #endif 4391155Sbill printf("%9d traps\n", sum.v_trap); 4401155Sbill printf("%9d system calls\n", sum.v_syscall); 44115807Smckusick lseek(mf, (long)nl[X_NCHSTATS].n_value, 0); 44218761Ssam read(mf, &nchstats, sizeof nchstats); 44318761Ssam nchtotal = nchstats.ncs_goodhits + nchstats.ncs_badhits + 44418761Ssam nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long; 44515807Smckusick printf("%9d total name lookups", nchtotal); 44615807Smckusick printf(" (cache hits %d%% system %d%% per-process)\n", 44729664Ssam pct(nchstats.ncs_goodhits, nchtotal), 44829664Ssam pct(nchstats.ncs_pass2, nchtotal)); 44916586Ssam printf("%9s badhits %d, falsehits %d, toolong %d\n", "", 45018761Ssam nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long); 45125512Ssam lseek(mf, (long)nl[X_XSTATS].n_value, 0); 45225512Ssam read(mf, &xstats, sizeof xstats); 45325512Ssam printf("%9d total calls to xalloc (cache hits %d%%)\n", 45429664Ssam xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc)); 45525512Ssam printf("%9s sticky %d flushed %d unused %d\n", "", 45625512Ssam xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused); 45725512Ssam printf("%9d total calls to xfree", xstats.free); 45825512Ssam printf(" (sticky %d cached %d swapped %d)\n", 45925512Ssam xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap); 46025960Ssam #if defined(tahoe) 46125960Ssam lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0); 46225960Ssam read(mf, &keystats, sizeof keystats); 46325960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 46425960Ssam keystats.ks_allocs, "code cache keys allocated", 46533610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 46629664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 46729664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 46829664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 46925960Ssam lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0); 47025960Ssam read(mf, &keystats, sizeof keystats); 47125960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 47225960Ssam keystats.ks_allocs, "data cache keys allocated", 47333610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 47429664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 47529664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 47629664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 47725960Ssam #endif 4781155Sbill } 4791155Sbill 4801155Sbill doforkst() 4811155Sbill { 4821155Sbill 48318761Ssam lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET); 4841155Sbill read(mf, &forkstat, sizeof forkstat); 4851155Sbill printf("%d forks, %d pages, average=%.2f\n", 4861155Sbill forkstat.cntfork, forkstat.sizfork, 4871155Sbill (float) forkstat.sizfork / forkstat.cntfork); 4881155Sbill printf("%d vforks, %d pages, average=%.2f\n", 4891155Sbill forkstat.cntvfork, forkstat.sizvfork, 4901155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 4911155Sbill } 4921155Sbill 4931155Sbill stats(dn) 4941155Sbill { 4951155Sbill 49618761Ssam if (dn >= dk_ndrive) { 4971155Sbill printf(" 0"); 4981155Sbill return; 4991155Sbill } 5001448Sbill printf("%3.0f", s.xfer[dn]/etime); 5011155Sbill } 5021155Sbill 5031155Sbill double 5041155Sbill stat1(row) 5051155Sbill { 5061448Sbill double t; 5071448Sbill register i; 5081155Sbill 5091155Sbill t = 0; 5101155Sbill for(i=0; i<CPUSTATES; i++) 5111448Sbill t += s.time[i]; 5121448Sbill if(t == 0.) 5131448Sbill t = 1.; 5141448Sbill return(s.time[row]*100./t); 5151155Sbill } 5161155Sbill 5171155Sbill pct(top, bot) 5181155Sbill { 5191155Sbill 5201155Sbill if (bot == 0) 5211155Sbill return (0); 5221155Sbill return ((top * 100) / bot); 5231155Sbill } 5243162Stoy 52517262Smckusick dointr(nintv) 52617262Smckusick { 52717262Smckusick int nintr, inttotal; 52817262Smckusick long *intrcnt; 52917262Smckusick char *intrname, *malloc(); 53017262Smckusick 53117262Smckusick nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long); 53217262Smckusick intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value - 53317262Smckusick nl[X_INTRCNT].n_value); 53417262Smckusick intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 53517262Smckusick if (intrcnt == NULL || intrname == NULL) { 53617262Smckusick fprintf(stderr, "vmstat: out of memory\n"); 53717262Smckusick exit(9); 53817262Smckusick } 53918761Ssam lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET); 54017262Smckusick read(mf, intrcnt, nintr * sizeof (long)); 54118761Ssam lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET); 54217262Smckusick read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 54317262Smckusick printf("interrupt total rate\n"); 54417262Smckusick inttotal = 0; 54517262Smckusick while (nintr--) { 54617262Smckusick if (*intrcnt) 54717262Smckusick printf("%-12s %8ld %8ld\n", intrname, 54817262Smckusick *intrcnt, *intrcnt / nintv); 54917262Smckusick intrname += strlen(intrname) + 1; 55017262Smckusick inttotal += *intrcnt++; 55117262Smckusick } 55217262Smckusick printf("Total %8ld %8ld\n", inttotal, inttotal / nintv); 55317262Smckusick } 55417262Smckusick 55533610Smckusick /* 55633610Smckusick * These names must be kept in sync with 55733610Smckusick * the types defined in <sys/malloc.h>. 55833610Smckusick */ 55933610Smckusick char *kmemnames[] = { 56036510Smarc "free", /* 0 M_FREE */ 56136510Smarc "mbuf", /* 1 M_MBUF */ 56236510Smarc "devbuf", /* 2 M_DEVBUF */ 56336510Smarc "socket", /* 3 M_SOCKET */ 56436510Smarc "pcb", /* 4 M_PCB */ 56536510Smarc "routetbl", /* 5 M_RTABLE */ 56636510Smarc "hosttbl", /* 6 M_HTABLE */ 56736510Smarc "fragtbl", /* 7 M_FTABLE */ 56836510Smarc "zombie", /* 8 M_ZOMBIE */ 56936510Smarc "ifaddr", /* 9 M_IFADDR */ 57036510Smarc "soopts", /* 10 M_SOOPTS */ 57136510Smarc "soname", /* 11 M_SONAME */ 57236510Smarc "namei", /* 12 M_NAMEI */ 57336510Smarc "gprof", /* 13 M_GPROF */ 57436510Smarc "ioctlops", /* 14 M_IOCTLOPS */ 57536510Smarc "superblk", /* 15 M_SUPERBLK */ 57636510Smarc "cred", /* 16 M_CRED */ 57736510Smarc "pgrp", /* 17 M_PGRP */ 57836510Smarc "session", /* 18 M_SESSION */ 57936513Smarc "iov", /* 19 M_IOV */ 580*38262Smckusick "mount", /* 20 M_MOUNT */ 581*38262Smckusick "fhandle", /* 21 M_FHANDLE */ 582*38262Smckusick "NFS req", /* 22 M_NFSREQ */ 583*38262Smckusick "NFS mount", /* 23 M_NFSMNT */ 58436510Smarc 0, 0, 0, 0, 0, 58536510Smarc 0, 0, 0, 0, 0, 58636510Smarc 0, 0, 0, 0, 0, 58736510Smarc 0, 0, 0, 0, 0, 58836510Smarc 0, 0, 0, 0, 0, 58936510Smarc "temp", /* 49 M_TEMP */ 59033610Smckusick }; 59133610Smckusick 59233610Smckusick domem() 59333610Smckusick { 59433610Smckusick struct kmemstats kmemstats[M_LAST]; 59533610Smckusick struct kmembuckets buckets[MINBUCKET + 16]; 59633610Smckusick register struct kmembuckets *kp; 59733610Smckusick register struct kmemstats *ks; 59833610Smckusick int i; 59933610Smckusick 60033610Smckusick lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET); 60133610Smckusick read(mf, buckets, sizeof buckets); 60233610Smckusick printf("Memory statistics by bucket size\n"); 60333610Smckusick printf(" Size In Use Free Requests HighWater Couldfree\n"); 60433610Smckusick for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) { 60533610Smckusick if (kp->kb_calls == 0) 60633610Smckusick continue; 60733610Smckusick printf("%8d%9d%7d%11d%8d%11d\n", 1 << i, 60833610Smckusick kp->kb_total - kp->kb_totalfree, 60933610Smckusick kp->kb_totalfree, kp->kb_calls, 61033610Smckusick kp->kb_highwat, kp->kb_couldfree); 61133610Smckusick 61233610Smckusick } 61333610Smckusick lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET); 61433610Smckusick read(mf, kmemstats, sizeof kmemstats); 61533610Smckusick printf("Memory statistics by type\n"); 61633610Smckusick printf(" Type In Use MemUse HighUse Limit Requests %s\n", 61733610Smckusick "TypeLimit KernLimit"); 61833610Smckusick for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) { 61933610Smckusick if (ks->ks_calls == 0) 62033610Smckusick continue; 62133610Smckusick printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n", 62233610Smckusick kmemnames[i] ? kmemnames[i] : "undefined", 62333610Smckusick ks->ks_inuse, (ks->ks_memuse + 1023) / 1024, 62433610Smckusick (ks->ks_maxused + 1023) / 1024, 62533610Smckusick (ks->ks_limit + 1023) / 1024, ks->ks_calls, 62633610Smckusick ks->ks_limblocks, ks->ks_mapblocks); 62733610Smckusick } 62833610Smckusick } 62933610Smckusick 63018761Ssam #define steal(where, var) \ 63118761Ssam lseek(mf, where, L_SET); read(mf, &var, sizeof var); 6323162Stoy /* 6333162Stoy * Read the drive names out of kmem. 6343162Stoy */ 63510826Ssam #ifdef vax 63618761Ssam #include <vaxuba/ubavar.h> 63718761Ssam #include <vaxmba/mbavar.h> 63818761Ssam 6393162Stoy read_names() 6403162Stoy { 6413162Stoy struct mba_device mdev; 6423162Stoy register struct mba_device *mp; 6433162Stoy struct mba_driver mdrv; 6443162Stoy short two_char; 6453162Stoy char *cp = (char *) &two_char; 6463162Stoy struct uba_device udev, *up; 6473162Stoy struct uba_driver udrv; 6483162Stoy 6493162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 6503162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 6513492Sroot if (up == 0) { 65210826Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 6533162Stoy exit(1); 6543162Stoy } 6553492Sroot if (mp) for (;;) { 6563162Stoy steal(mp++, mdev); 6573162Stoy if (mdev.mi_driver == 0) 6583162Stoy break; 6593162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 6603162Stoy continue; 6613162Stoy steal(mdev.mi_driver, mdrv); 6623162Stoy steal(mdrv.md_dname, two_char); 66318761Ssam sprintf(dr_name[mdev.mi_dk], "%c%c%d", 66418761Ssam cp[0], cp[1], mdev.mi_unit); 6653162Stoy } 6663492Sroot for (;;) { 6673162Stoy steal(up++, udev); 6683162Stoy if (udev.ui_driver == 0) 6693162Stoy break; 6703162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 6713162Stoy continue; 6723162Stoy steal(udev.ui_driver, udrv); 6733162Stoy steal(udrv.ud_dname, two_char); 67418761Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 67518761Ssam cp[0], cp[1], udev.ui_unit); 6763162Stoy } 6773162Stoy } 67810826Ssam #endif 67925708Ssam 68025708Ssam #ifdef tahoe 68125708Ssam #include <tahoevba/vbavar.h> 68225708Ssam 68325708Ssam /* 68425708Ssam * Read the drive names out of kmem. 68525708Ssam */ 68625708Ssam read_names() 68725708Ssam { 68825708Ssam struct vba_device udev, *up; 68925708Ssam struct vba_driver udrv; 69025708Ssam short two_char; 69125708Ssam char *cp = (char *)&two_char; 69225708Ssam 69325708Ssam up = (struct vba_device *) nl[X_VBDINIT].n_value; 69425708Ssam if (up == 0) { 69525708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 69625708Ssam exit(1); 69725708Ssam } 69825708Ssam for (;;) { 69925708Ssam steal(up++, udev); 70025708Ssam if (udev.ui_driver == 0) 70125708Ssam break; 70225708Ssam if (udev.ui_dk < 0 || udev.ui_alive == 0) 70325708Ssam continue; 70425708Ssam steal(udev.ui_driver, udrv); 70525708Ssam steal(udrv.ud_dname, two_char); 70625708Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 70725708Ssam cp[0], cp[1], udev.ui_unit); 70825708Ssam } 70925708Ssam } 71025708Ssam #endif 711