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*37912Sbostic static char sccsid[] = "@(#)vmstat.c 5.13 (Berkeley) 05/11/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> 38*37912Sbostic #include <stdio.h> 39*37912Sbostic #include <ctype.h> 40*37912Sbostic #include <nlist.h> 41*37912Sbostic #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 158*37912Sbostic nlist(_PATH_UNIX, nl); 1591155Sbill if(nl[0].n_type == 0) { 160*37912Sbostic fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX); 1611155Sbill exit(1); 1621155Sbill } 163*37912Sbostic mf = open(_PATH_KMEM, 0); 1641155Sbill if(mf < 0) { 165*37912Sbostic 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); 181*37912Sbostic 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 */ 58036510Smarc 0, 0, 0, 0, 0, 58136510Smarc 0, 0, 0, 0, 0, 58236510Smarc 0, 0, 0, 0, 0, 58336510Smarc 0, 0, 0, 0, 0, 58436510Smarc 0, 0, 0, 0, 0, 58536513Smarc 0, 0, 0, 0, 58636510Smarc "temp", /* 49 M_TEMP */ 58733610Smckusick }; 58833610Smckusick 58933610Smckusick domem() 59033610Smckusick { 59133610Smckusick struct kmemstats kmemstats[M_LAST]; 59233610Smckusick struct kmembuckets buckets[MINBUCKET + 16]; 59333610Smckusick register struct kmembuckets *kp; 59433610Smckusick register struct kmemstats *ks; 59533610Smckusick int i; 59633610Smckusick 59733610Smckusick lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET); 59833610Smckusick read(mf, buckets, sizeof buckets); 59933610Smckusick printf("Memory statistics by bucket size\n"); 60033610Smckusick printf(" Size In Use Free Requests HighWater Couldfree\n"); 60133610Smckusick for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) { 60233610Smckusick if (kp->kb_calls == 0) 60333610Smckusick continue; 60433610Smckusick printf("%8d%9d%7d%11d%8d%11d\n", 1 << i, 60533610Smckusick kp->kb_total - kp->kb_totalfree, 60633610Smckusick kp->kb_totalfree, kp->kb_calls, 60733610Smckusick kp->kb_highwat, kp->kb_couldfree); 60833610Smckusick 60933610Smckusick } 61033610Smckusick lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET); 61133610Smckusick read(mf, kmemstats, sizeof kmemstats); 61233610Smckusick printf("Memory statistics by type\n"); 61333610Smckusick printf(" Type In Use MemUse HighUse Limit Requests %s\n", 61433610Smckusick "TypeLimit KernLimit"); 61533610Smckusick for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) { 61633610Smckusick if (ks->ks_calls == 0) 61733610Smckusick continue; 61833610Smckusick printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n", 61933610Smckusick kmemnames[i] ? kmemnames[i] : "undefined", 62033610Smckusick ks->ks_inuse, (ks->ks_memuse + 1023) / 1024, 62133610Smckusick (ks->ks_maxused + 1023) / 1024, 62233610Smckusick (ks->ks_limit + 1023) / 1024, ks->ks_calls, 62333610Smckusick ks->ks_limblocks, ks->ks_mapblocks); 62433610Smckusick } 62533610Smckusick } 62633610Smckusick 62718761Ssam #define steal(where, var) \ 62818761Ssam lseek(mf, where, L_SET); read(mf, &var, sizeof var); 6293162Stoy /* 6303162Stoy * Read the drive names out of kmem. 6313162Stoy */ 63210826Ssam #ifdef vax 63318761Ssam #include <vaxuba/ubavar.h> 63418761Ssam #include <vaxmba/mbavar.h> 63518761Ssam 6363162Stoy read_names() 6373162Stoy { 6383162Stoy struct mba_device mdev; 6393162Stoy register struct mba_device *mp; 6403162Stoy struct mba_driver mdrv; 6413162Stoy short two_char; 6423162Stoy char *cp = (char *) &two_char; 6433162Stoy struct uba_device udev, *up; 6443162Stoy struct uba_driver udrv; 6453162Stoy 6463162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 6473162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 6483492Sroot if (up == 0) { 64910826Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 6503162Stoy exit(1); 6513162Stoy } 6523492Sroot if (mp) for (;;) { 6533162Stoy steal(mp++, mdev); 6543162Stoy if (mdev.mi_driver == 0) 6553162Stoy break; 6563162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 6573162Stoy continue; 6583162Stoy steal(mdev.mi_driver, mdrv); 6593162Stoy steal(mdrv.md_dname, two_char); 66018761Ssam sprintf(dr_name[mdev.mi_dk], "%c%c%d", 66118761Ssam cp[0], cp[1], mdev.mi_unit); 6623162Stoy } 6633492Sroot for (;;) { 6643162Stoy steal(up++, udev); 6653162Stoy if (udev.ui_driver == 0) 6663162Stoy break; 6673162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 6683162Stoy continue; 6693162Stoy steal(udev.ui_driver, udrv); 6703162Stoy steal(udrv.ud_dname, two_char); 67118761Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 67218761Ssam cp[0], cp[1], udev.ui_unit); 6733162Stoy } 6743162Stoy } 67510826Ssam #endif 67625708Ssam 67725708Ssam #ifdef tahoe 67825708Ssam #include <tahoevba/vbavar.h> 67925708Ssam 68025708Ssam /* 68125708Ssam * Read the drive names out of kmem. 68225708Ssam */ 68325708Ssam read_names() 68425708Ssam { 68525708Ssam struct vba_device udev, *up; 68625708Ssam struct vba_driver udrv; 68725708Ssam short two_char; 68825708Ssam char *cp = (char *)&two_char; 68925708Ssam 69025708Ssam up = (struct vba_device *) nl[X_VBDINIT].n_value; 69125708Ssam if (up == 0) { 69225708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 69325708Ssam exit(1); 69425708Ssam } 69525708Ssam for (;;) { 69625708Ssam steal(up++, udev); 69725708Ssam if (udev.ui_driver == 0) 69825708Ssam break; 69925708Ssam if (udev.ui_dk < 0 || udev.ui_alive == 0) 70025708Ssam continue; 70125708Ssam steal(udev.ui_driver, udrv); 70225708Ssam steal(udrv.ud_dname, two_char); 70325708Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 70425708Ssam cp[0], cp[1], udev.ui_unit); 70525708Ssam } 70625708Ssam } 70725708Ssam #endif 708