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*38773Smckusick static char sccsid[] = "@(#)vmstat.c 5.16 (Berkeley) 08/26/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> 3438263Smckusick #include <sys/time.h> 3538263Smckusick #include <sys/vnode.h> 3638263Smckusick #include <ufs/inode.h> 3717262Smckusick #include <sys/namei.h> 3825708Ssam #include <sys/text.h> 3933610Smckusick #include <sys/malloc.h> 4037912Sbostic #include <stdio.h> 4137912Sbostic #include <ctype.h> 4237912Sbostic #include <nlist.h> 4337912Sbostic #include <paths.h> 441155Sbill 451155Sbill struct nlist nl[] = { 461448Sbill #define X_CPTIME 0 471448Sbill { "_cp_time" }, 481448Sbill #define X_RATE 1 491155Sbill { "_rate" }, 501448Sbill #define X_TOTAL 2 511155Sbill { "_total" }, 521448Sbill #define X_DEFICIT 3 531155Sbill { "_deficit" }, 541448Sbill #define X_FORKSTAT 4 551155Sbill { "_forkstat" }, 561448Sbill #define X_SUM 5 571155Sbill { "_sum" }, 581448Sbill #define X_FIRSTFREE 6 591155Sbill { "_firstfree" }, 601448Sbill #define X_MAXFREE 7 611155Sbill { "_maxfree" }, 629249Ssam #define X_BOOTTIME 8 639249Ssam { "_boottime" }, 641448Sbill #define X_DKXFER 9 651448Sbill { "_dk_xfer" }, 6610826Ssam #define X_REC 10 671155Sbill { "_rectime" }, 6810826Ssam #define X_PGIN 11 691155Sbill { "_pgintime" }, 7010826Ssam #define X_HZ 12 713162Stoy { "_hz" }, 7218761Ssam #define X_PHZ 13 7315266Ssam { "_phz" }, 7415807Smckusick #define X_NCHSTATS 14 7515807Smckusick { "_nchstats" }, 7617262Smckusick #define X_INTRNAMES 15 7717262Smckusick { "_intrnames" }, 7817262Smckusick #define X_EINTRNAMES 16 7917262Smckusick { "_eintrnames" }, 8017262Smckusick #define X_INTRCNT 17 8117262Smckusick { "_intrcnt" }, 8217262Smckusick #define X_EINTRCNT 18 8317262Smckusick { "_eintrcnt" }, 8418761Ssam #define X_DK_NDRIVE 19 8518761Ssam { "_dk_ndrive" }, 8625512Ssam #define X_XSTATS 20 8725512Ssam { "_xstats" }, 8833610Smckusick #define X_KMEMSTAT 21 8933610Smckusick { "_kmemstats" }, 9033610Smckusick #define X_KMEMBUCKETS 22 9133610Smckusick { "_bucket" }, 9210826Ssam #ifdef vax 9325708Ssam #define X_MBDINIT (X_XSTATS+1) 9410826Ssam { "_mbdinit" }, 9525708Ssam #define X_UBDINIT (X_XSTATS+2) 9610826Ssam { "_ubdinit" }, 9710826Ssam #endif 9825708Ssam #ifdef tahoe 9925708Ssam #define X_VBDINIT (X_XSTATS+1) 10025708Ssam { "_vbdinit" }, 10125960Ssam #define X_CKEYSTATS (X_XSTATS+2) 10225960Ssam { "_ckeystats" }, 10325960Ssam #define X_DKEYSTATS (X_XSTATS+3) 10425960Ssam { "_dkeystats" }, 10525708Ssam #endif 10610826Ssam { "" }, 1071155Sbill }; 1081155Sbill 10918761Ssam char **dr_name; 11018761Ssam int *dr_select; 11118761Ssam int dk_ndrive; 11218761Ssam int ndrives = 0; 11318761Ssam #ifdef vax 11418761Ssam char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; 11518761Ssam #else 11618761Ssam char *defdrives[] = { 0 }; 11718761Ssam #endif 1181155Sbill double stat1(); 1191155Sbill int firstfree, maxfree; 1203162Stoy int hz; 12115266Ssam int phz; 12215266Ssam int HZ; 12318761Ssam 12418761Ssam struct { 1251155Sbill int busy; 1261448Sbill long time[CPUSTATES]; 12718761Ssam long *xfer; 1281155Sbill struct vmmeter Rate; 1291155Sbill struct vmtotal Total; 1301155Sbill struct vmmeter Sum; 1311155Sbill struct forkstat Forkstat; 1321155Sbill unsigned rectime; 1331155Sbill unsigned pgintime; 1341155Sbill } s, s1, z; 1351155Sbill #define rate s.Rate 1361155Sbill #define total s.Total 1371155Sbill #define sum s.Sum 1381155Sbill #define forkstat s.Forkstat 1391155Sbill 14010826Ssam struct vmmeter osum; 1411155Sbill int deficit; 1421155Sbill double etime; 1431155Sbill int mf; 14417262Smckusick time_t now, boottime; 14517262Smckusick int printhdr(); 14618768Ssam int lines = 1; 1471155Sbill 14829664Ssam #define INTS(x) ((x) - (hz + phz)) 14929664Ssam 1501155Sbill main(argc, argv) 15110826Ssam int argc; 15210826Ssam char **argv; 1531155Sbill { 1541155Sbill extern char *ctime(); 15529664Ssam register i; 15617262Smckusick int iter, nintv, iflag = 0; 1571155Sbill long t; 15829664Ssam char *arg, **cp, buf[BUFSIZ]; 1591155Sbill 16037912Sbostic nlist(_PATH_UNIX, nl); 1611155Sbill if(nl[0].n_type == 0) { 16237912Sbostic fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX); 1631155Sbill exit(1); 1641155Sbill } 16537912Sbostic mf = open(_PATH_KMEM, 0); 1661155Sbill if(mf < 0) { 16737912Sbostic fprintf(stderr, "vmstat: cannot open %s\n", _PATH_KMEM); 1681155Sbill exit(1); 1691155Sbill } 1701155Sbill iter = 0; 1711155Sbill argc--, argv++; 1721155Sbill while (argc>0 && argv[0][0]=='-') { 1731155Sbill char *cp = *argv++; 1741155Sbill argc--; 1751155Sbill while (*++cp) switch (*cp) { 1761155Sbill 1771155Sbill case 't': 1781155Sbill dotimes(); 1791155Sbill exit(0); 18010826Ssam 1811155Sbill case 'z': 1821155Sbill close(mf); 18337912Sbostic mf = open(_PATH_KMEM, 2); 18418761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 1851155Sbill write(mf, &z.Sum, sizeof z.Sum); 1861155Sbill exit(0); 1871155Sbill 1881155Sbill case 'f': 1891155Sbill doforkst(); 1901155Sbill exit(0); 1911155Sbill 19233610Smckusick case 'm': 19333610Smckusick domem(); 19433610Smckusick exit(0); 19533610Smckusick 1961155Sbill case 's': 1971155Sbill dosum(); 1981155Sbill exit(0); 1991155Sbill 20017262Smckusick case 'i': 20117262Smckusick iflag++; 20217262Smckusick break; 20317262Smckusick 2041155Sbill default: 20518761Ssam fprintf(stderr, 20633610Smckusick "usage: vmstat [ -fsim ] [ interval ] [ count]\n"); 2071155Sbill exit(1); 2081155Sbill } 2091155Sbill } 21018761Ssam lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET); 2111155Sbill read(mf, &firstfree, sizeof firstfree); 21218761Ssam lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET); 2131155Sbill read(mf, &maxfree, sizeof maxfree); 21418761Ssam lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET); 2159249Ssam read(mf, &boottime, sizeof boottime); 21618761Ssam lseek(mf, (long)nl[X_HZ].n_value, L_SET); 2173162Stoy read(mf, &hz, sizeof hz); 21818761Ssam if (nl[X_PHZ].n_value != 0) { 21918761Ssam lseek(mf, (long)nl[X_PHZ].n_value, L_SET); 22018761Ssam read(mf, &phz, sizeof phz); 22118761Ssam } 22215266Ssam HZ = phz ? phz : hz; 22330266Sbostic if (nl[X_DK_NDRIVE].n_value == 0) { 22429664Ssam fprintf(stderr, "dk_ndrive undefined in system\n"); 22518761Ssam exit(1); 2263162Stoy } 22718761Ssam lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET); 22818761Ssam read(mf, &dk_ndrive, sizeof (dk_ndrive)); 22918761Ssam if (dk_ndrive <= 0) { 23029664Ssam fprintf(stderr, "dk_ndrive %d\n", dk_ndrive); 23118761Ssam exit(1); 23218761Ssam } 23318761Ssam dr_select = (int *)calloc(dk_ndrive, sizeof (int)); 23418761Ssam dr_name = (char **)calloc(dk_ndrive, sizeof (char *)); 23518761Ssam #define allocate(e, t) \ 23618761Ssam s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 23718761Ssam s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); 23818761Ssam allocate(xfer, long); 23918761Ssam for (arg = buf, i = 0; i < dk_ndrive; i++) { 24018761Ssam dr_name[i] = arg; 24118761Ssam sprintf(dr_name[i], "dk%d", i); 24218761Ssam arg += strlen(dr_name[i]) + 1; 24318761Ssam } 2443162Stoy read_names(); 2451155Sbill time(&now); 2469249Ssam nintv = now - boottime; 2471155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 24829664Ssam fprintf(stderr, 24929664Ssam "Time makes no sense... namelist must be wrong.\n"); 2501155Sbill exit(1); 2511155Sbill } 25217262Smckusick if (iflag) { 25317262Smckusick dointr(nintv); 25417262Smckusick exit(0); 25517262Smckusick } 25618761Ssam /* 25718761Ssam * Choose drives to be displayed. Priority 25818761Ssam * goes to (in order) drives supplied as arguments, 25918761Ssam * default drives. If everything isn't filled 26018761Ssam * in and there are drives not taken care of, 26118761Ssam * display the first few that fit. 26218761Ssam */ 26318761Ssam ndrives = 0; 26418761Ssam while (argc > 0 && !isdigit(argv[0][0])) { 26518761Ssam for (i = 0; i < dk_ndrive; i++) { 26618761Ssam if (strcmp(dr_name[i], argv[0])) 26718761Ssam continue; 26818761Ssam dr_select[i] = 1; 26918761Ssam ndrives++; 27018761Ssam } 27118761Ssam argc--, argv++; 27218761Ssam } 27318761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 27418761Ssam if (dr_select[i]) 27518761Ssam continue; 27618761Ssam for (cp = defdrives; *cp; cp++) 27718761Ssam if (strcmp(dr_name[i], *cp) == 0) { 27818761Ssam dr_select[i] = 1; 27918761Ssam ndrives++; 28018761Ssam break; 28118761Ssam } 28218761Ssam } 28318761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 28418761Ssam if (dr_select[i]) 28518761Ssam continue; 28618761Ssam dr_select[i] = 1; 28718761Ssam ndrives++; 28818761Ssam } 28918761Ssam if (argc > 1) 29018761Ssam iter = atoi(argv[1]); 29117262Smckusick signal(SIGCONT, printhdr); 2921155Sbill loop: 29318768Ssam if (--lines == 0) 29418768Ssam printhdr(); 29518761Ssam lseek(mf, (long)nl[X_CPTIME].n_value, L_SET); 2961448Sbill read(mf, s.time, sizeof s.time); 29718761Ssam lseek(mf, (long)nl[X_DKXFER].n_value, L_SET); 29818761Ssam read(mf, s.xfer, dk_ndrive * sizeof (long)); 29918761Ssam if (nintv != 1) 30018761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 30118761Ssam else 30218761Ssam lseek(mf, (long)nl[X_RATE].n_value, L_SET); 30318761Ssam read(mf, &rate, sizeof rate); 30418761Ssam lseek(mf, (long)nl[X_TOTAL].n_value, L_SET); 3051155Sbill read(mf, &total, sizeof total); 30610826Ssam osum = sum; 30718761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 30810826Ssam read(mf, &sum, sizeof sum); 30918761Ssam lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET); 3101155Sbill read(mf, &deficit, sizeof deficit); 3111448Sbill etime = 0; 31218761Ssam for (i=0; i < dk_ndrive; i++) { 3131448Sbill t = s.xfer[i]; 3141448Sbill s.xfer[i] -= s1.xfer[i]; 3151448Sbill s1.xfer[i] = t; 3161155Sbill } 3171155Sbill for (i=0; i < CPUSTATES; i++) { 3181448Sbill t = s.time[i]; 3191448Sbill s.time[i] -= s1.time[i]; 3201448Sbill s1.time[i] = t; 3211448Sbill etime += s.time[i]; 3221155Sbill } 3231155Sbill if(etime == 0.) 3241155Sbill etime = 1.; 3253162Stoy printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); 32610826Ssam #define pgtok(a) ((a)*NBPG/1024) 32729664Ssam printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free)); 32815266Ssam printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 32915266Ssam (rate.v_xsfrec+rate.v_xifrec)/nintv); 33010826Ssam printf("%4d", pgtok(rate.v_pgpgin)/nintv); 33110826Ssam printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv, 33210826Ssam pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv); 33318761Ssam etime /= (float)HZ; 33418761Ssam for (i = 0; i < dk_ndrive; i++) 33518761Ssam if (dr_select[i]) 33618761Ssam stats(i); 33715266Ssam printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv, 33815266Ssam rate.v_swtch/nintv); 3391155Sbill for(i=0; i<CPUSTATES; i++) { 3401155Sbill float f = stat1(i); 3411155Sbill if (i == 0) { /* US+NI */ 3421155Sbill i++; 3431155Sbill f += stat1(i); 3441155Sbill } 3451155Sbill printf("%3.0f", f); 3461155Sbill } 3471155Sbill printf("\n"); 3481155Sbill fflush(stdout); 3491155Sbill nintv = 1; 35018768Ssam if (--iter &&argc > 0) { 3511155Sbill sleep(atoi(argv[0])); 3521155Sbill goto loop; 3531155Sbill } 3541155Sbill } 3551155Sbill 35617262Smckusick printhdr() 35717262Smckusick { 35818761Ssam register int i, j; 35918761Ssam 36029664Ssam printf(" procs memory page "); 36118761Ssam i = (ndrives * 3 - 6) / 2; 36218761Ssam if (i < 0) 36318761Ssam i = 0; 36418761Ssam for (j = 0; j < i; j++) 36518761Ssam putchar(' '); 36618761Ssam printf("faults"); 36718761Ssam i = ndrives * 3 - 6 - i; 36818761Ssam for (j = 0; j < i; j++) 36918761Ssam putchar(' '); 37018761Ssam printf(" cpu\n"); 37129664Ssam printf(" r b w avm fre re at pi po fr de sr "); 37218761Ssam for (i = 0; i < dk_ndrive; i++) 37318761Ssam if (dr_select[i]) 37418761Ssam printf("%c%c ", dr_name[i][0], dr_name[i][2]); 37518761Ssam printf(" in sy cs us sy id\n"); 37618768Ssam lines = 19; 37717262Smckusick } 37817262Smckusick 3791155Sbill dotimes() 3801155Sbill { 3811155Sbill 38218761Ssam lseek(mf, (long)nl[X_REC].n_value, L_SET); 3831155Sbill read(mf, &s.rectime, sizeof s.rectime); 38418761Ssam lseek(mf, (long)nl[X_PGIN].n_value, L_SET); 3851155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 38618761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3871155Sbill read(mf, &sum, sizeof sum); 3881155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 3891155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 3901155Sbill printf("\n"); 3911155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 3921155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 3931155Sbill } 3941155Sbill 39530069Ssam #if defined(tahoe) 39630069Ssam #include <tahoe/cpu.h> 39730069Ssam #endif 39830069Ssam 3991155Sbill dosum() 4001155Sbill { 40118761Ssam struct nchstats nchstats; 40225960Ssam struct xstats xstats; 40315807Smckusick long nchtotal; 40425960Ssam #if defined(tahoe) 40525960Ssam struct keystats keystats; 40625960Ssam #endif 4071155Sbill 40818761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 4091155Sbill read(mf, &sum, sizeof sum); 4101155Sbill printf("%9d swap ins\n", sum.v_swpin); 4111155Sbill printf("%9d swap outs\n", sum.v_swpout); 4121155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 4131155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 4141155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 4151155Sbill printf("%9d page ins\n", sum.v_pgin); 4161155Sbill printf("%9d page outs\n", sum.v_pgout); 4173612Sroot printf("%9d pages paged in\n", sum.v_pgpgin); 4183612Sroot printf("%9d pages paged out\n", sum.v_pgpgout); 4193612Sroot printf("%9d sequential process pages freed\n", sum.v_seqfree); 42012830Ssam printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec, 42129664Ssam pct(sum.v_fastpgrec, sum.v_pgrec)); 4221155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 4231155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 4241155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 4251155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 4261155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 4271155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 4281155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 4291155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 4301155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 4311155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 4321155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 4331155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 4341155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 4351155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 4361155Sbill printf("%9d device interrupts\n", sum.v_intr); 43717262Smckusick printf("%9d software interrupts\n", sum.v_soft); 43818761Ssam #ifdef vax 43924429Smckusick printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma); 44018761Ssam #endif 4411155Sbill printf("%9d traps\n", sum.v_trap); 4421155Sbill printf("%9d system calls\n", sum.v_syscall); 44315807Smckusick lseek(mf, (long)nl[X_NCHSTATS].n_value, 0); 44418761Ssam read(mf, &nchstats, sizeof nchstats); 445*38773Smckusick nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits + 446*38773Smckusick nchstats.ncs_badhits + nchstats.ncs_falsehits + 447*38773Smckusick nchstats.ncs_miss + nchstats.ncs_long; 448*38773Smckusick printf("%9d total name lookups\n", nchtotal); 449*38773Smckusick printf("%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n", 450*38773Smckusick "", pct(nchstats.ncs_goodhits, nchtotal), 451*38773Smckusick pct(nchstats.ncs_neghits, nchtotal), 45229664Ssam pct(nchstats.ncs_pass2, nchtotal)); 453*38773Smckusick printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "", 454*38773Smckusick pct(nchstats.ncs_badhits, nchtotal), 455*38773Smckusick pct(nchstats.ncs_falsehits, nchtotal), 456*38773Smckusick pct(nchstats.ncs_long, nchtotal)); 45725512Ssam lseek(mf, (long)nl[X_XSTATS].n_value, 0); 45825512Ssam read(mf, &xstats, sizeof xstats); 45925512Ssam printf("%9d total calls to xalloc (cache hits %d%%)\n", 46029664Ssam xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc)); 46125512Ssam printf("%9s sticky %d flushed %d unused %d\n", "", 46225512Ssam xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused); 46325512Ssam printf("%9d total calls to xfree", xstats.free); 46425512Ssam printf(" (sticky %d cached %d swapped %d)\n", 46525512Ssam xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap); 46625960Ssam #if defined(tahoe) 46725960Ssam lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0); 46825960Ssam read(mf, &keystats, sizeof keystats); 46925960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 47025960Ssam keystats.ks_allocs, "code cache keys allocated", 47133610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 47229664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 47329664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 47429664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 47525960Ssam lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0); 47625960Ssam read(mf, &keystats, sizeof keystats); 47725960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 47825960Ssam keystats.ks_allocs, "data cache keys allocated", 47933610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 48029664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 48129664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 48229664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 48325960Ssam #endif 4841155Sbill } 4851155Sbill 4861155Sbill doforkst() 4871155Sbill { 4881155Sbill 48918761Ssam lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET); 4901155Sbill read(mf, &forkstat, sizeof forkstat); 4911155Sbill printf("%d forks, %d pages, average=%.2f\n", 4921155Sbill forkstat.cntfork, forkstat.sizfork, 4931155Sbill (float) forkstat.sizfork / forkstat.cntfork); 4941155Sbill printf("%d vforks, %d pages, average=%.2f\n", 4951155Sbill forkstat.cntvfork, forkstat.sizvfork, 4961155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 4971155Sbill } 4981155Sbill 4991155Sbill stats(dn) 5001155Sbill { 5011155Sbill 50218761Ssam if (dn >= dk_ndrive) { 5031155Sbill printf(" 0"); 5041155Sbill return; 5051155Sbill } 5061448Sbill printf("%3.0f", s.xfer[dn]/etime); 5071155Sbill } 5081155Sbill 5091155Sbill double 5101155Sbill stat1(row) 5111155Sbill { 5121448Sbill double t; 5131448Sbill register i; 5141155Sbill 5151155Sbill t = 0; 5161155Sbill for(i=0; i<CPUSTATES; i++) 5171448Sbill t += s.time[i]; 5181448Sbill if(t == 0.) 5191448Sbill t = 1.; 5201448Sbill return(s.time[row]*100./t); 5211155Sbill } 5221155Sbill 5231155Sbill pct(top, bot) 5241155Sbill { 5251155Sbill 5261155Sbill if (bot == 0) 5271155Sbill return (0); 5281155Sbill return ((top * 100) / bot); 5291155Sbill } 5303162Stoy 53117262Smckusick dointr(nintv) 53217262Smckusick { 53317262Smckusick int nintr, inttotal; 53417262Smckusick long *intrcnt; 53517262Smckusick char *intrname, *malloc(); 53617262Smckusick 53717262Smckusick nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long); 53817262Smckusick intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value - 53917262Smckusick nl[X_INTRCNT].n_value); 54017262Smckusick intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 54117262Smckusick if (intrcnt == NULL || intrname == NULL) { 54217262Smckusick fprintf(stderr, "vmstat: out of memory\n"); 54317262Smckusick exit(9); 54417262Smckusick } 54518761Ssam lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET); 54617262Smckusick read(mf, intrcnt, nintr * sizeof (long)); 54718761Ssam lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET); 54817262Smckusick read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 54917262Smckusick printf("interrupt total rate\n"); 55017262Smckusick inttotal = 0; 55117262Smckusick while (nintr--) { 55217262Smckusick if (*intrcnt) 55317262Smckusick printf("%-12s %8ld %8ld\n", intrname, 55417262Smckusick *intrcnt, *intrcnt / nintv); 55517262Smckusick intrname += strlen(intrname) + 1; 55617262Smckusick inttotal += *intrcnt++; 55717262Smckusick } 55817262Smckusick printf("Total %8ld %8ld\n", inttotal, inttotal / nintv); 55917262Smckusick } 56017262Smckusick 56133610Smckusick /* 56233610Smckusick * These names must be kept in sync with 56333610Smckusick * the types defined in <sys/malloc.h>. 56433610Smckusick */ 56533610Smckusick char *kmemnames[] = { 56636510Smarc "free", /* 0 M_FREE */ 56736510Smarc "mbuf", /* 1 M_MBUF */ 56836510Smarc "devbuf", /* 2 M_DEVBUF */ 56936510Smarc "socket", /* 3 M_SOCKET */ 57036510Smarc "pcb", /* 4 M_PCB */ 57136510Smarc "routetbl", /* 5 M_RTABLE */ 57236510Smarc "hosttbl", /* 6 M_HTABLE */ 57336510Smarc "fragtbl", /* 7 M_FTABLE */ 57436510Smarc "zombie", /* 8 M_ZOMBIE */ 57536510Smarc "ifaddr", /* 9 M_IFADDR */ 57636510Smarc "soopts", /* 10 M_SOOPTS */ 57736510Smarc "soname", /* 11 M_SONAME */ 57836510Smarc "namei", /* 12 M_NAMEI */ 57936510Smarc "gprof", /* 13 M_GPROF */ 58036510Smarc "ioctlops", /* 14 M_IOCTLOPS */ 58136510Smarc "superblk", /* 15 M_SUPERBLK */ 58236510Smarc "cred", /* 16 M_CRED */ 58336510Smarc "pgrp", /* 17 M_PGRP */ 58436510Smarc "session", /* 18 M_SESSION */ 58536513Smarc "iov", /* 19 M_IOV */ 58638262Smckusick "mount", /* 20 M_MOUNT */ 58738262Smckusick "fhandle", /* 21 M_FHANDLE */ 58838262Smckusick "NFS req", /* 22 M_NFSREQ */ 58938262Smckusick "NFS mount", /* 23 M_NFSMNT */ 59036510Smarc 0, 0, 0, 0, 0, 59136510Smarc 0, 0, 0, 0, 0, 59236510Smarc 0, 0, 0, 0, 0, 59336510Smarc 0, 0, 0, 0, 0, 59436510Smarc 0, 0, 0, 0, 0, 59536510Smarc "temp", /* 49 M_TEMP */ 59633610Smckusick }; 59733610Smckusick 59833610Smckusick domem() 59933610Smckusick { 60033610Smckusick struct kmemstats kmemstats[M_LAST]; 60133610Smckusick struct kmembuckets buckets[MINBUCKET + 16]; 60233610Smckusick register struct kmembuckets *kp; 60333610Smckusick register struct kmemstats *ks; 60433610Smckusick int i; 60533610Smckusick 60633610Smckusick lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET); 60733610Smckusick read(mf, buckets, sizeof buckets); 60833610Smckusick printf("Memory statistics by bucket size\n"); 60933610Smckusick printf(" Size In Use Free Requests HighWater Couldfree\n"); 61033610Smckusick for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) { 61133610Smckusick if (kp->kb_calls == 0) 61233610Smckusick continue; 61333610Smckusick printf("%8d%9d%7d%11d%8d%11d\n", 1 << i, 61433610Smckusick kp->kb_total - kp->kb_totalfree, 61533610Smckusick kp->kb_totalfree, kp->kb_calls, 61633610Smckusick kp->kb_highwat, kp->kb_couldfree); 61733610Smckusick 61833610Smckusick } 61933610Smckusick lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET); 62033610Smckusick read(mf, kmemstats, sizeof kmemstats); 62133610Smckusick printf("Memory statistics by type\n"); 62233610Smckusick printf(" Type In Use MemUse HighUse Limit Requests %s\n", 62333610Smckusick "TypeLimit KernLimit"); 62433610Smckusick for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) { 62533610Smckusick if (ks->ks_calls == 0) 62633610Smckusick continue; 62733610Smckusick printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n", 62833610Smckusick kmemnames[i] ? kmemnames[i] : "undefined", 62933610Smckusick ks->ks_inuse, (ks->ks_memuse + 1023) / 1024, 63033610Smckusick (ks->ks_maxused + 1023) / 1024, 63133610Smckusick (ks->ks_limit + 1023) / 1024, ks->ks_calls, 63233610Smckusick ks->ks_limblocks, ks->ks_mapblocks); 63333610Smckusick } 63433610Smckusick } 63533610Smckusick 63618761Ssam #define steal(where, var) \ 63718761Ssam lseek(mf, where, L_SET); read(mf, &var, sizeof var); 6383162Stoy /* 6393162Stoy * Read the drive names out of kmem. 6403162Stoy */ 64110826Ssam #ifdef vax 64218761Ssam #include <vaxuba/ubavar.h> 64318761Ssam #include <vaxmba/mbavar.h> 64418761Ssam 6453162Stoy read_names() 6463162Stoy { 6473162Stoy struct mba_device mdev; 6483162Stoy register struct mba_device *mp; 6493162Stoy struct mba_driver mdrv; 6503162Stoy short two_char; 6513162Stoy char *cp = (char *) &two_char; 6523162Stoy struct uba_device udev, *up; 6533162Stoy struct uba_driver udrv; 6543162Stoy 6553162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 6563162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 6573492Sroot if (up == 0) { 65810826Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 6593162Stoy exit(1); 6603162Stoy } 6613492Sroot if (mp) for (;;) { 6623162Stoy steal(mp++, mdev); 6633162Stoy if (mdev.mi_driver == 0) 6643162Stoy break; 6653162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 6663162Stoy continue; 6673162Stoy steal(mdev.mi_driver, mdrv); 6683162Stoy steal(mdrv.md_dname, two_char); 66918761Ssam sprintf(dr_name[mdev.mi_dk], "%c%c%d", 67018761Ssam cp[0], cp[1], mdev.mi_unit); 6713162Stoy } 6723492Sroot for (;;) { 6733162Stoy steal(up++, udev); 6743162Stoy if (udev.ui_driver == 0) 6753162Stoy break; 6763162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 6773162Stoy continue; 6783162Stoy steal(udev.ui_driver, udrv); 6793162Stoy steal(udrv.ud_dname, two_char); 68018761Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 68118761Ssam cp[0], cp[1], udev.ui_unit); 6823162Stoy } 6833162Stoy } 68410826Ssam #endif 68525708Ssam 68625708Ssam #ifdef tahoe 68725708Ssam #include <tahoevba/vbavar.h> 68825708Ssam 68925708Ssam /* 69025708Ssam * Read the drive names out of kmem. 69125708Ssam */ 69225708Ssam read_names() 69325708Ssam { 69425708Ssam struct vba_device udev, *up; 69525708Ssam struct vba_driver udrv; 69625708Ssam short two_char; 69725708Ssam char *cp = (char *)&two_char; 69825708Ssam 69925708Ssam up = (struct vba_device *) nl[X_VBDINIT].n_value; 70025708Ssam if (up == 0) { 70125708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 70225708Ssam exit(1); 70325708Ssam } 70425708Ssam for (;;) { 70525708Ssam steal(up++, udev); 70625708Ssam if (udev.ui_driver == 0) 70725708Ssam break; 70825708Ssam if (udev.ui_dk < 0 || udev.ui_alive == 0) 70925708Ssam continue; 71025708Ssam steal(udev.ui_driver, udrv); 71125708Ssam steal(udrv.ud_dname, two_char); 71225708Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 71325708Ssam cp[0], cp[1], udev.ui_unit); 71425708Ssam } 71525708Ssam } 71625708Ssam #endif 717