Annotation of src/usr.bin/vmstat/vmstat.c, Revision 1.52
1.11 deraadt 1: /* $NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $ */
1.52 ! angelos 2: /* $OpenBSD: vmstat.c,v 1.51 2001/04/30 13:54:51 art Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1980, 1986, 1991, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1980, 1986, 1991, 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93";
46: #else
1.11 deraadt 47: static char rcsid[] = "$NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $";
1.1 deraadt 48: #endif
49: #endif /* not lint */
50:
1.48 art 51: #define __POOL_EXPOSE
52:
1.1 deraadt 53: #include <sys/param.h>
54: #include <sys/time.h>
55: #include <sys/proc.h>
56: #include <sys/user.h>
57: #include <sys/dkstat.h>
58: #include <sys/buf.h>
59: #include <sys/namei.h>
60: #include <sys/malloc.h>
61: #include <sys/fcntl.h>
62: #include <sys/ioctl.h>
63: #include <sys/sysctl.h>
64: #include <sys/device.h>
1.48 art 65: #include <sys/pool.h>
1.1 deraadt 66: #include <vm/vm.h>
67: #include <time.h>
68: #include <nlist.h>
69: #include <kvm.h>
1.21 millert 70: #include <err.h>
1.1 deraadt 71: #include <errno.h>
72: #include <unistd.h>
73: #include <signal.h>
74: #include <stdio.h>
75: #include <ctype.h>
76: #include <stdlib.h>
77: #include <string.h>
78: #include <paths.h>
79: #include <limits.h>
1.6 tholo 80: #include "dkstats.h"
1.1 deraadt 81:
1.29 art 82: #ifdef UVM
83: #include <uvm/uvm_extern.h>
84: #endif
85:
1.1 deraadt 86: struct nlist namelist[] = {
87: #define X_CPTIME 0
88: { "_cp_time" },
1.29 art 89: #if defined(UVM)
90: #define X_UVMEXP 1
91: { "_uvmexp" },
92: #else
1.23 deraadt 93: #define X_SUM 1
1.1 deraadt 94: { "_cnt" },
1.29 art 95: #endif
1.23 deraadt 96: #define X_BOOTTIME 2
1.1 deraadt 97: { "_boottime" },
1.23 deraadt 98: #define X_HZ 3
1.1 deraadt 99: { "_hz" },
1.23 deraadt 100: #define X_STATHZ 4
1.1 deraadt 101: { "_stathz" },
1.23 deraadt 102: #define X_NCHSTATS 5
1.1 deraadt 103: { "_nchstats" },
1.23 deraadt 104: #define X_INTRNAMES 6
1.1 deraadt 105: { "_intrnames" },
1.23 deraadt 106: #define X_EINTRNAMES 7
1.1 deraadt 107: { "_eintrnames" },
1.23 deraadt 108: #define X_INTRCNT 8
1.1 deraadt 109: { "_intrcnt" },
1.23 deraadt 110: #define X_EINTRCNT 9
1.1 deraadt 111: { "_eintrcnt" },
1.23 deraadt 112: #define X_KMEMSTAT 10
1.1 deraadt 113: { "_kmemstats" },
1.23 deraadt 114: #define X_KMEMBUCKETS 11
1.1 deraadt 115: { "_bucket" },
1.23 deraadt 116: #define X_ALLEVENTS 12
1.1 deraadt 117: { "_allevents" },
1.23 deraadt 118: #define X_FORKSTAT 13
1.12 tholo 119: { "_forkstat" },
1.48 art 120: #define X_POOLHEAD 14
121: { "_pool_head" },
1.51 art 122: #define X_NSELCOLL 15
1.50 art 123: { "_nselcoll" },
124: #define X_END 16
1.28 espie 125: #if defined(__pc532__)
1.1 deraadt 126: #define X_IVT (X_END)
127: { "_ivt" },
128: #endif
1.28 espie 129: #if defined(__i386__)
1.12 tholo 130: #define X_INTRHAND (X_END)
131: { "_intrhand" },
132: #define X_INTRSTRAY (X_END+1)
133: { "_intrstray" },
134: #endif
1.1 deraadt 135: { "" },
136: };
137:
1.6 tholo 138: /* Objects defined in dkstats.c */
139: extern struct _disk cur;
1.10 deraadt 140: extern char **dr_name;
141: extern int *dk_select, dk_ndrive;
1.1 deraadt 142:
1.29 art 143: #ifdef UVM
144: struct uvmexp uvmexp, ouvmexp;
145: #else
1.1 deraadt 146: struct vmmeter sum, osum;
1.29 art 147: #endif
1.6 tholo 148: int ndrives;
1.1 deraadt 149:
150: int winlines = 20;
151:
152: kvm_t *kd;
153:
154: #define FORKSTAT 0x01
155: #define INTRSTAT 0x02
156: #define MEMSTAT 0x04
157: #define SUMSTAT 0x08
158: #define TIMESTAT 0x10
159: #define VMSTAT 0x20
160:
1.10 deraadt 161: void cpustats __P((void));
162: void dkstats __P((void));
163: void dointr __P((void));
164: void domem __P((void));
1.48 art 165: void dopool __P((void));
1.10 deraadt 166: void dosum __P((void));
167: void dovmstat __P((u_int, int));
168: void kread __P((int, void *, size_t));
169: void usage __P((void));
170: void dotimes __P((void));
171: void doforkst __P((void));
1.21 millert 172: void printhdr __P((void));
1.1 deraadt 173:
1.10 deraadt 174: char **choosedrives __P((char **));
175:
176: /* Namelist and memory file names. */
177: char *nlistf, *memf;
1.6 tholo 178:
1.50 art 179: extern char *__progname;
180:
1.21 millert 181: int
1.1 deraadt 182: main(argc, argv)
183: register int argc;
184: register char **argv;
185: {
186: extern int optind;
187: extern char *optarg;
188: register int c, todo;
189: u_int interval;
190: int reps;
1.25 deraadt 191: char errbuf[_POSIX2_LINE_MAX];
1.1 deraadt 192:
193: memf = nlistf = NULL;
194: interval = reps = todo = 0;
1.16 millert 195: while ((c = getopt(argc, argv, "c:fiM:mN:stw:")) != -1) {
1.1 deraadt 196: switch (c) {
197: case 'c':
198: reps = atoi(optarg);
199: break;
200: case 'f':
201: todo |= FORKSTAT;
202: break;
203: case 'i':
204: todo |= INTRSTAT;
205: break;
206: case 'M':
207: memf = optarg;
208: break;
209: case 'm':
210: todo |= MEMSTAT;
211: break;
212: case 'N':
213: nlistf = optarg;
214: break;
215: case 's':
216: todo |= SUMSTAT;
217: break;
218: case 't':
219: todo |= TIMESTAT;
220: break;
221: case 'w':
222: interval = atoi(optarg);
223: break;
224: case '?':
225: default:
226: usage();
227: }
228: }
229: argc -= optind;
230: argv += optind;
231:
232: if (todo == 0)
233: todo = VMSTAT;
234:
235: /*
236: * Discard setgid privileges if not the running kernel so that bad
237: * guys can't print interesting stuff from kernel memory.
238: */
1.15 tholo 239: if (nlistf != NULL || memf != NULL) {
240: setegid(getgid());
1.1 deraadt 241: setgid(getgid());
1.15 tholo 242: }
1.1 deraadt 243:
1.25 deraadt 244: kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
1.50 art 245: if (kd == 0)
246: errx(1, "kvm_openfiles: %s", errbuf);
1.1 deraadt 247:
248: if ((c = kvm_nlist(kd, namelist)) != 0) {
1.25 deraadt 249:
250: setegid(getgid());
251: setgid(getgid());
252:
1.1 deraadt 253: if (c > 0) {
254: (void)fprintf(stderr,
1.50 art 255: "%s: undefined symbols:", __progname);
1.1 deraadt 256: for (c = 0;
257: c < sizeof(namelist)/sizeof(namelist[0]); c++)
258: if (namelist[c].n_type == 0)
259: fprintf(stderr, " %s",
260: namelist[c].n_name);
261: (void)fputc('\n', stderr);
1.50 art 262: exit(1);
1.1 deraadt 263: } else
1.50 art 264: errx(1, "kvm_nlist: %s", kvm_geterr(kd));
1.1 deraadt 265: }
266:
267: if (todo & VMSTAT) {
268: struct winsize winsize;
269:
1.6 tholo 270: dkinit(0); /* Initialize disk stats, no disks selected. */
271: argv = choosedrives(argv); /* Select disks. */
1.1 deraadt 272: winsize.ws_row = 0;
273: (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize);
274: if (winsize.ws_row > 0)
275: winlines = winsize.ws_row;
276:
277: }
1.25 deraadt 278:
279: setegid(getgid());
280: setgid(getgid());
1.1 deraadt 281:
282: #define BACKWARD_COMPATIBILITY
283: #ifdef BACKWARD_COMPATIBILITY
284: if (*argv) {
285: interval = atoi(*argv);
286: if (*++argv)
287: reps = atoi(*argv);
288: }
289: #endif
290:
291: if (interval) {
292: if (!reps)
293: reps = -1;
294: } else if (reps)
295: interval = 1;
296:
297: if (todo & FORKSTAT)
298: doforkst();
1.48 art 299: if (todo & MEMSTAT) {
1.1 deraadt 300: domem();
1.48 art 301: dopool();
302: }
1.1 deraadt 303: if (todo & SUMSTAT)
304: dosum();
305: if (todo & TIMESTAT)
306: dotimes();
307: if (todo & INTRSTAT)
308: dointr();
309: if (todo & VMSTAT)
310: dovmstat(interval, reps);
311: exit(0);
312: }
313:
314: char **
1.6 tholo 315: choosedrives(argv)
1.1 deraadt 316: char **argv;
317: {
318: register int i;
319:
320: /*
321: * Choose drives to be displayed. Priority goes to (in order) drives
322: * supplied as arguments, default drives. If everything isn't filled
323: * in and there are drives not taken care of, display the first few
324: * that fit.
325: */
326: #define BACKWARD_COMPATIBILITY
327: for (ndrives = 0; *argv; ++argv) {
328: #ifdef BACKWARD_COMPATIBILITY
329: if (isdigit(**argv))
330: break;
331: #endif
332: for (i = 0; i < dk_ndrive; i++) {
333: if (strcmp(dr_name[i], *argv))
334: continue;
1.6 tholo 335: dk_select[i] = 1;
1.1 deraadt 336: ++ndrives;
337: break;
338: }
339: }
340: for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
1.6 tholo 341: if (dk_select[i])
1.1 deraadt 342: continue;
1.6 tholo 343: dk_select[i] = 1;
1.1 deraadt 344: ++ndrives;
345: }
346: return(argv);
347: }
348:
1.19 deraadt 349: time_t
1.1 deraadt 350: getuptime()
351: {
1.11 deraadt 352: static time_t now;
353: static struct timeval boottime;
1.1 deraadt 354: time_t uptime;
1.50 art 355: int mib[2];
356: size_t size;
1.1 deraadt 357:
1.50 art 358: if (boottime.tv_sec == 0) {
359: if (nlist == NULL && memf == NULL) {
360: kread(X_BOOTTIME, &boottime, sizeof(boottime));
361: } else {
362: size = sizeof(boottime);
363: mib[0] = CTL_KERN;
364: mib[1] = KERN_BOOTTIME;
365: if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) {
366: printf("Can't get kerninfo: %s\n",
367: strerror(errno));
368: bzero(&boottime, sizeof(boottime));
369: }
370: }
371: }
1.1 deraadt 372: (void)time(&now);
1.11 deraadt 373: uptime = now - boottime.tv_sec;
1.50 art 374: if (uptime <= 0 || uptime > 60*60*24*365*10)
375: errx(1, "time makes no sense; namelist must be wrong");
376:
1.1 deraadt 377: return(uptime);
378: }
379:
380: int hz, hdrcnt;
381:
382: void
383: dovmstat(interval, reps)
384: u_int interval;
385: int reps;
386: {
387: struct vmtotal total;
388: time_t uptime, halfuptime;
389: void needhdr();
390: int mib[2];
1.50 art 391: struct clockinfo clkinfo;
1.1 deraadt 392: size_t size;
393:
394: uptime = getuptime();
395: halfuptime = uptime / 2;
396: (void)signal(SIGCONT, needhdr);
397:
1.50 art 398: mib[0] = CTL_KERN;
399: mib[1] = KERN_CLOCKRATE;
400: size = sizeof(clkinfo);
401: if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) {
402: printf("Can't get kerninfo: %s\n", strerror(errno));
403: return;
404: }
405: hz = clkinfo.stathz;
1.1 deraadt 406:
407: for (hdrcnt = 1;;) {
408: if (!--hdrcnt)
409: printhdr();
1.6 tholo 410: /* Read new disk statistics */
411: dkreadstats();
1.29 art 412: #ifdef UVM
1.52 ! angelos 413: if (nlist == NULL && memf == NULL) {
! 414: kread(X_UVMEXP, &uvmexp, sizeof(uvmexp));
! 415: } else {
! 416: size = sizeof(uvmexp);
! 417: mib[0] = CTL_VM;
! 418: mib[1] = VM_UVMEXP;
! 419: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
! 420: printf("Can't get kerninfo: %s\n",
! 421: strerror(errno));
! 422: bzero(&uvmexp, sizeof(uvmexp));
! 423: }
! 424: }
1.29 art 425: #else
1.1 deraadt 426: kread(X_SUM, &sum, sizeof(sum));
1.29 art 427: #endif
1.1 deraadt 428: size = sizeof(total);
429: mib[0] = CTL_VM;
430: mib[1] = VM_METER;
431: if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) {
432: printf("Can't get kerninfo: %s\n", strerror(errno));
433: bzero(&total, sizeof(total));
434: }
1.22 millert 435: (void)printf("%2u%2u%2u",
1.1 deraadt 436: total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw);
1.29 art 437: #define rate(x) (((x) + halfuptime) / uptime) /* round */
438: #ifdef UVM
439: #define pgtok(a) ((a) * ((int)uvmexp.pagesize >> 10))
440: #else
1.22 millert 441: #define pgtok(a) ((a) * ((int)sum.v_page_size >> 10))
1.29 art 442: #endif
1.35 hugh 443: (void)printf("%7u%7u ",
1.1 deraadt 444: pgtok(total.t_avm), pgtok(total.t_free));
1.29 art 445: #ifdef UVM
446: (void)printf("%4u ", rate(uvmexp.faults - ouvmexp.faults));
447: (void)printf("%3u ", rate(uvmexp.pdreact - ouvmexp.pdreact));
448: (void)printf("%3u ", rate(uvmexp.pageins - ouvmexp.pageins));
449: (void)printf("%3u %3u ",
450: rate(uvmexp.pdpageouts - ouvmexp.pdpageouts), 0);
451: (void)printf("%3u ", rate(uvmexp.pdscans - ouvmexp.pdscans));
452: dkstats();
453: (void)printf("%4u %4u %3u ",
454: rate(uvmexp.intrs - ouvmexp.intrs),
455: rate(uvmexp.syscalls - ouvmexp.syscalls),
456: rate(uvmexp.swtch - ouvmexp.swtch));
457: #else
1.21 millert 458: (void)printf("%4u ", rate(sum.v_faults - osum.v_faults));
459: (void)printf("%3u ",
1.1 deraadt 460: rate(sum.v_reactivated - osum.v_reactivated));
1.21 millert 461: (void)printf("%3u ", rate(sum.v_pageins - osum.v_pageins));
462: (void)printf("%3u %3u ",
1.1 deraadt 463: rate(sum.v_pageouts - osum.v_pageouts), 0);
1.21 millert 464: (void)printf("%3u ", rate(sum.v_scan - osum.v_scan));
1.1 deraadt 465: dkstats();
1.21 millert 466: (void)printf("%4u %4u %3u ",
1.1 deraadt 467: rate(sum.v_intr - osum.v_intr),
468: rate(sum.v_syscall - osum.v_syscall),
469: rate(sum.v_swtch - osum.v_swtch));
1.29 art 470: #endif
1.1 deraadt 471: cpustats();
472: (void)printf("\n");
473: (void)fflush(stdout);
474: if (reps >= 0 && --reps <= 0)
475: break;
1.31 art 476: #ifdef UVM
1.29 art 477: ouvmexp = uvmexp;
1.31 art 478: #else
479: osum = sum;
480: #endif
1.1 deraadt 481: uptime = interval;
482: /*
483: * We round upward to avoid losing low-frequency events
484: * (i.e., >= 1 per interval but < 1 per second).
485: */
1.14 deraadt 486: halfuptime = uptime == 1 ? 0 : (uptime + 1) / 2;
1.1 deraadt 487: (void)sleep(interval);
488: }
489: }
490:
1.21 millert 491: void
1.1 deraadt 492: printhdr()
493: {
494: register int i;
495:
1.35 hugh 496: (void)printf(" procs memory page%*s", 20, "");
1.6 tholo 497: if (ndrives > 0)
498: (void)printf("%s %*sfaults cpu\n",
499: ((ndrives > 1) ? "disks" : "disk"),
500: ((ndrives > 1) ? ndrives * 3 - 4 : 0), "");
1.1 deraadt 501: else
1.6 tholo 502: (void)printf("%*s faults cpu\n",
503: ndrives * 3, "");
504:
1.35 hugh 505: (void)printf(" r b w avm fre flt re pi po fr sr ");
1.1 deraadt 506: for (i = 0; i < dk_ndrive; i++)
1.6 tholo 507: if (dk_select[i])
1.1 deraadt 508: (void)printf("%c%c ", dr_name[i][0],
509: dr_name[i][strlen(dr_name[i]) - 1]);
510: (void)printf(" in sy cs us sy id\n");
511: hdrcnt = winlines - 2;
512: }
513:
514: /*
515: * Force a header to be prepended to the next output.
516: */
517: void
518: needhdr()
519: {
520:
521: hdrcnt = 1;
522: }
523:
524: void
525: dotimes()
526: {
527: u_int pgintime, rectime;
1.52 ! angelos 528: int mib[2];
! 529: size_t size;
1.1 deraadt 530:
1.12 tholo 531: pgintime = 0;
532: rectime = 0;
1.29 art 533: #ifdef UVM
1.52 ! angelos 534: if (nlist == NULL && memf == NULL) {
! 535: kread(X_UVMEXP, &uvmexp, sizeof(uvmexp));
! 536: } else {
! 537: size = sizeof(uvmexp);
! 538: mib[0] = CTL_VM;
! 539: mib[1] = VM_UVMEXP;
! 540: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
! 541: printf("Can't get kerninfo: %s\n", strerror(errno));
! 542: bzero(&uvmexp, sizeof(uvmexp));
! 543: }
! 544: }
! 545:
1.29 art 546: (void)printf("%u reactivates, %u total time (usec)\n",
547: uvmexp.pdreact, rectime);
548: (void)printf("average: %u usec / reclaim\n", rectime / uvmexp.pdreact);
549: (void)printf("\n");
550: (void)printf("%u page ins, %u total time (msec)\n",
551: uvmexp.pageins, pgintime / 10);
552: (void)printf("average: %8.1f msec / page in\n",
553: pgintime / (uvmexp.pageins * 10.0));
554: #else
1.1 deraadt 555: kread(X_SUM, &sum, sizeof(sum));
1.12 tholo 556: (void)printf("%u reactivates, %u total time (usec)\n",
557: sum.v_reactivated, rectime);
558: (void)printf("average: %u usec / reclaim\n", rectime / sum.v_reactivated);
1.1 deraadt 559: (void)printf("\n");
560: (void)printf("%u page ins, %u total time (msec)\n",
1.12 tholo 561: sum.v_pageins, pgintime / 10);
1.1 deraadt 562: (void)printf("average: %8.1f msec / page in\n",
1.12 tholo 563: pgintime / (sum.v_pageins * 10.0));
1.29 art 564: #endif
1.1 deraadt 565: }
566:
1.21 millert 567: int
1.1 deraadt 568: pct(top, bot)
569: long top, bot;
570: {
571: long ans;
572:
573: if (bot == 0)
574: return(0);
575: ans = (quad_t)top * 100 / bot;
576: return (ans);
577: }
578:
579: #define PCT(top, bot) pct((long)(top), (long)(bot))
580:
581: void
582: dosum()
583: {
584: struct nchstats nchstats;
585: long nchtotal;
1.52 ! angelos 586: size_t size;
! 587: int mib[2], nselcoll;
1.1 deraadt 588:
1.29 art 589: #ifdef UVM
1.52 ! angelos 590: if (nlist == NULL && memf == NULL) {
! 591: kread(X_UVMEXP, &nchstats, sizeof(uvmexp));
! 592: } else {
! 593: size = sizeof(uvmexp);
! 594: mib[0] = CTL_VM;
! 595: mib[1] = VM_UVMEXP;
! 596: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
! 597: printf("Can't get kerninfo: %s\n", strerror(errno));
! 598: bzero(&uvmexp, sizeof(uvmexp));
! 599: }
! 600: }
! 601:
1.32 art 602: /* vm_page constants */
1.35 hugh 603: (void)printf("%11u bytes per page\n", uvmexp.pagesize);
1.32 art 604:
605: /* vm_page counters */
1.35 hugh 606: (void)printf("%11u pages managed\n", uvmexp.npages);
607: (void)printf("%11u pages free\n", uvmexp.free);
608: (void)printf("%11u pages active\n", uvmexp.active);
609: (void)printf("%11u pages inactive\n", uvmexp.inactive);
610: (void)printf("%11u pages being paged out\n", uvmexp.paging);
611: (void)printf("%11u pages wired\n", uvmexp.wired);
612: (void)printf("%11u pages reserved for pagedaemon\n",
1.48 art 613: uvmexp.reserve_pagedaemon);
1.35 hugh 614: (void)printf("%11u pages reserved for kernel\n",
1.48 art 615: uvmexp.reserve_kernel);
1.32 art 616:
617: /* swap */
1.35 hugh 618: (void)printf("%11u swap pages\n", uvmexp.swpages);
619: (void)printf("%11u swap pages in use\n", uvmexp.swpginuse);
620: (void)printf("%11u total anon's in system\n", uvmexp.nanon);
621: (void)printf("%11u free anon's\n", uvmexp.nfreeanon);
1.32 art 622:
623: /* stat counters */
1.35 hugh 624: (void)printf("%11u page faults\n", uvmexp.faults);
625: (void)printf("%11u traps\n", uvmexp.traps);
626: (void)printf("%11u interrupts\n", uvmexp.intrs);
627: (void)printf("%11u cpu context switches\n", uvmexp.swtch);
628: (void)printf("%11u software interrupts\n", uvmexp.softs);
629: (void)printf("%11u syscalls\n", uvmexp.syscalls);
630: (void)printf("%11u pagein operations\n", uvmexp.pageins);
631: (void)printf("%11u swap ins\n", uvmexp.swapins);
632: (void)printf("%11u swap outs\n", uvmexp.swapouts);
633: (void)printf("%11u forks\n", uvmexp.forks);
634: (void)printf("%11u forks where vmspace is shared\n",
1.48 art 635: uvmexp.forks_sharevm);
1.32 art 636:
637: /* daemon counters */
1.37 art 638: (void)printf("%11u number of times the pagedeamon woke up\n",
1.48 art 639: uvmexp.pdwoke);
1.35 hugh 640: (void)printf("%11u revolutions of the clock hand\n", uvmexp.pdrevs);
641: (void)printf("%11u pages freed by pagedaemon\n", uvmexp.pdfreed);
642: (void)printf("%11u pages scanned by pagedaemon\n", uvmexp.pdscans);
643: (void)printf("%11u pages reactivated by pagedaemon\n", uvmexp.pdreact);
644: (void)printf("%11u busy pages found by pagedaemon\n", uvmexp.pdbusy);
1.29 art 645: #else
1.1 deraadt 646: kread(X_SUM, &sum, sizeof(sum));
1.35 hugh 647: (void)printf("%11u cpu context switches\n", sum.v_swtch);
648: (void)printf("%11u device interrupts\n", sum.v_intr);
649: (void)printf("%11u software interrupts\n", sum.v_soft);
650: (void)printf("%11u traps\n", sum.v_trap);
651: (void)printf("%11u system calls\n", sum.v_syscall);
652: (void)printf("%11u total faults taken\n", sum.v_faults);
653: (void)printf("%11u swap ins\n", sum.v_swpin);
654: (void)printf("%11u swap outs\n", sum.v_swpout);
1.49 art 655: (void)printf("%11u pages swapped in\n", sum.v_pswpin);
656: (void)printf("%11u pages swapped out\n", sum.v_pswpout);
1.35 hugh 657: (void)printf("%11u page ins\n", sum.v_pageins);
658: (void)printf("%11u page outs\n", sum.v_pageouts);
659: (void)printf("%11u pages paged in\n", sum.v_pgpgin);
660: (void)printf("%11u pages paged out\n", sum.v_pgpgout);
661: (void)printf("%11u pages reactivated\n", sum.v_reactivated);
662: (void)printf("%11u intransit blocking page faults\n", sum.v_intrans);
1.49 art 663: (void)printf("%11u zero fill pages created\n", sum.v_nzfod);
664: (void)printf("%11u zero fill page faults\n", sum.v_zfod);
1.35 hugh 665: (void)printf("%11u pages examined by the clock daemon\n", sum.v_scan);
666: (void)printf("%11u revolutions of the clock hand\n", sum.v_rev);
667: (void)printf("%11u VM object cache lookups\n", sum.v_lookups);
668: (void)printf("%11u VM object hits\n", sum.v_hits);
669: (void)printf("%11u total VM faults taken\n", sum.v_vm_faults);
670: (void)printf("%11u copy-on-write faults\n", sum.v_cow_faults);
671: (void)printf("%11u pages freed by daemon\n", sum.v_dfree);
672: (void)printf("%11u pages freed by exiting processes\n", sum.v_pfree);
673: (void)printf("%11u pages free\n", sum.v_free_count);
674: (void)printf("%11u pages wired down\n", sum.v_wire_count);
675: (void)printf("%11u pages active\n", sum.v_active_count);
676: (void)printf("%11u pages inactive\n", sum.v_inactive_count);
677: (void)printf("%11u bytes per page\n", sum.v_page_size);
1.29 art 678: #endif
679:
1.52 ! angelos 680: if (nlist == NULL && memf == NULL) {
! 681: kread(X_NCHSTATS, &nchstats, sizeof(nchstats));
! 682: } else {
! 683: size = sizeof(nchstats);
! 684: mib[0] = CTL_KERN;
! 685: mib[1] = KERN_NCHSTATS;
! 686: if (sysctl(mib, 2, &nchstats, &size, NULL, 0) < 0) {
! 687: printf("Can't get kerninfo: %s\n", strerror(errno));
! 688: bzero(&nchstats, sizeof(nchstats));
! 689: }
! 690: }
! 691:
1.1 deraadt 692: nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
693: nchstats.ncs_badhits + nchstats.ncs_falsehits +
694: nchstats.ncs_miss + nchstats.ncs_long;
1.35 hugh 695: (void)printf("%11ld total name lookups\n", nchtotal);
1.52 ! angelos 696: (void)printf("%11s cache hits (%d%% pos + %d%% neg) system %d%% "
! 697: "per-directory\n",
1.1 deraadt 698: "", PCT(nchstats.ncs_goodhits, nchtotal),
699: PCT(nchstats.ncs_neghits, nchtotal),
700: PCT(nchstats.ncs_pass2, nchtotal));
1.35 hugh 701: (void)printf("%11s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
1.1 deraadt 702: PCT(nchstats.ncs_badhits, nchtotal),
703: PCT(nchstats.ncs_falsehits, nchtotal),
704: PCT(nchstats.ncs_long, nchtotal));
1.52 ! angelos 705:
! 706: if (nlist == NULL && memf == NULL) {
! 707: kread(X_NSELCOLL, &nselcoll, sizeof(nselcoll));
! 708: } else {
! 709: size = sizeof(nselcoll);
! 710: mib[0] = CTL_KERN;
! 711: mib[1] = KERN_NSELCOLL;
! 712: if (sysctl(mib, 2, &nselcoll, &size, NULL, 0) < 0) {
! 713: printf("Can't get kerninfo: %s\n", strerror(errno));
! 714: nselcoll = 0;
! 715: }
! 716: }
1.50 art 717: (void)printf("%11d select collisions\n", nselcoll);
1.1 deraadt 718: }
719:
720: void
721: doforkst()
722: {
723: struct forkstat fks;
1.52 ! angelos 724: size_t size;
! 725: int mib[2];
! 726:
! 727: if (nlist == NULL && memf == NULL) {
! 728: kread(X_FORKSTAT, &fks, sizeof(struct forkstat));
! 729: } else {
! 730: size = sizeof(struct forkstat);
! 731: mib[0] = CTL_KERN;
! 732: mib[1] = KERN_FORKSTAT;
! 733: if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) {
! 734: printf("Can't get kerninfo: %s\n", strerror(errno));
! 735: bzero(&fks, sizeof(struct forkstat));
! 736: }
! 737: }
1.1 deraadt 738:
739: (void)printf("%d forks, %d pages, average %.2f\n",
740: fks.cntfork, fks.sizfork, (double)fks.sizfork / fks.cntfork);
741: (void)printf("%d vforks, %d pages, average %.2f\n",
1.12 tholo 742: fks.cntvfork, fks.sizvfork, (double)fks.sizvfork / (fks.cntvfork ? fks.cntvfork : 1));
743: (void)printf("%d rforks, %d pages, average %.2f\n",
744: fks.cntrfork, fks.sizrfork, (double)fks.sizrfork / (fks.cntrfork ? fks.cntrfork : 1));
1.36 niklas 745: (void)printf("%d kthread creations, %d pages, average %.2f\n",
746: fks.cntkthread, fks.sizkthread, (double)fks.sizkthread / (fks.cntkthread ? fks.cntkthread : 1));
1.1 deraadt 747: }
748:
749: void
750: dkstats()
751: {
752: register int dn, state;
753: double etime;
754:
1.6 tholo 755: /* Calculate disk stat deltas. */
756: dkswap();
1.1 deraadt 757: etime = 0;
758: for (state = 0; state < CPUSTATES; ++state) {
1.6 tholo 759: etime += cur.cp_time[state];
1.1 deraadt 760: }
761: if (etime == 0)
762: etime = 1;
763: etime /= hz;
764: for (dn = 0; dn < dk_ndrive; ++dn) {
1.6 tholo 765: if (!dk_select[dn])
1.1 deraadt 766: continue;
1.6 tholo 767: (void)printf("%2.0f ", cur.dk_xfer[dn] / etime);
1.1 deraadt 768: }
769: }
770:
771: void
772: cpustats()
773: {
774: register int state;
775: double pct, total;
776:
777: total = 0;
778: for (state = 0; state < CPUSTATES; ++state)
1.6 tholo 779: total += cur.cp_time[state];
1.1 deraadt 780: if (total)
781: pct = 100 / total;
782: else
783: pct = 0;
1.6 tholo 784: (void)printf("%2.0f ", (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * pct);
785: (void)printf("%2.0f ", (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * pct);
786: (void)printf("%2.0f", cur.cp_time[CP_IDLE] * pct);
1.1 deraadt 787: }
788:
1.28 espie 789: #if defined(__pc532__)
1.1 deraadt 790: /* To get struct iv ...*/
791: #define _KERNEL
792: #include <machine/psl.h>
793: #undef _KERNEL
794: void
795: dointr()
796: {
1.19 deraadt 797: register long i, j, inttotal;
798: time_t uptime;
1.1 deraadt 799: static char iname[64];
800: struct iv ivt[32], *ivp = ivt;
801:
802: iname[63] = '\0';
803: uptime = getuptime();
804: kread(X_IVT, ivp, sizeof(ivt));
805:
806: for (i = 0; i < 2; i++) {
807: (void)printf("%sware interrupts:\n", i ? "\nsoft" : "hard");
1.27 alex 808: (void)printf("interrupt total rate\n");
1.1 deraadt 809: inttotal = 0;
810: for (j = 0; j < 16; j++, ivp++) {
811: if (ivp->iv_vec && ivp->iv_use && ivp->iv_cnt) {
812: if (kvm_read(kd, (u_long)ivp->iv_use, iname, 63) != 63) {
1.50 art 813: errx(1, "iv_use: %s", kvm_geterr(kd));
1.1 deraadt 814: }
1.27 alex 815: (void)printf("%-12s %10ld %8ld\n", iname,
1.1 deraadt 816: ivp->iv_cnt, ivp->iv_cnt / uptime);
817: inttotal += ivp->iv_cnt;
818: }
819: }
1.27 alex 820: (void)printf("Total %10ld %8ld\n",
1.1 deraadt 821: inttotal, inttotal / uptime);
822: }
1.12 tholo 823: }
1.28 espie 824: #elif defined(__i386__)
1.12 tholo 825: /* To get struct intrhand */
1.13 tholo 826: #define _KERNEL
1.12 tholo 827: #include <machine/psl.h>
1.13 tholo 828: #undef _KERNEL
1.12 tholo 829: void
830: dointr()
831: {
832: struct intrhand *intrhand[16], *ihp, ih;
1.50 art 833: u_long inttotal;
1.19 deraadt 834: time_t uptime;
1.50 art 835: u_long intrstray[16];
1.34 deraadt 836: char iname[17], fname[31];
1.12 tholo 837: int i;
838:
839: iname[16] = '\0';
840: uptime = getuptime();
841: kread(X_INTRHAND, intrhand, sizeof(intrhand));
842: kread(X_INTRSTRAY, intrstray, sizeof(intrstray));
843:
1.27 alex 844: (void)printf("interrupt total rate\n");
1.12 tholo 845: inttotal = 0;
846: for (i = 0; i < 16; i++) {
847: ihp = intrhand[i];
848: while (ihp) {
849: if (kvm_read(kd, (u_long)ihp, &ih, sizeof(ih)) != sizeof(ih))
850: errx(1, "vmstat: ih: %s", kvm_geterr(kd));
851: if (kvm_read(kd, (u_long)ih.ih_what, iname, 16) != 16)
852: errx(1, "vmstat: ih_what: %s", kvm_geterr(kd));
1.34 deraadt 853: snprintf(fname, sizeof fname, "irq%d/%s", i, iname);
1.50 art 854: printf("%-16.16s %10lu %8lu\n", fname, ih.ih_count,
1.34 deraadt 855: ih.ih_count / uptime);
1.12 tholo 856: inttotal += ih.ih_count;
857: ihp = ih.ih_next;
858: }
859: }
860: for (i = 0; i < 16; i++)
861: if (intrstray[i]) {
1.50 art 862: printf("Stray irq %-2d %10lu %8lu\n",
1.12 tholo 863: i, intrstray[i], intrstray[i] / uptime);
864: inttotal += intrstray[i];
865: }
1.50 art 866: printf("Total %10lu %8lu\n", inttotal, inttotal / uptime);
1.1 deraadt 867: }
868: #else
869: void
870: dointr()
871: {
1.19 deraadt 872: register long *intrcnt, inttotal;
873: time_t uptime;
1.1 deraadt 874: register int nintr, inamlen;
875: register char *intrname;
1.9 deraadt 876: struct evcntlist allevents;
877: struct evcnt evcnt, *evptr;
1.1 deraadt 878: struct device dev;
879:
880: uptime = getuptime();
881: nintr = namelist[X_EINTRCNT].n_value - namelist[X_INTRCNT].n_value;
882: inamlen =
883: namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;
884: intrcnt = malloc((size_t)nintr);
885: intrname = malloc((size_t)inamlen);
1.50 art 886: if (intrcnt == NULL || intrname == NULL)
887: err(1, "malloc");
1.1 deraadt 888: kread(X_INTRCNT, intrcnt, (size_t)nintr);
889: kread(X_INTRNAMES, intrname, (size_t)inamlen);
1.27 alex 890: (void)printf("interrupt total rate\n");
1.1 deraadt 891: inttotal = 0;
892: nintr /= sizeof(long);
893: while (--nintr >= 0) {
894: if (*intrcnt)
1.27 alex 895: (void)printf("%-14s %12ld %8ld\n", intrname,
1.1 deraadt 896: *intrcnt, *intrcnt / uptime);
897: intrname += strlen(intrname) + 1;
898: inttotal += *intrcnt++;
899: }
900: kread(X_ALLEVENTS, &allevents, sizeof allevents);
1.9 deraadt 901: evptr = allevents.tqh_first;
902: while (evptr) {
903: if (kvm_read(kd, (long)evptr, (void *)&evcnt,
1.50 art 904: sizeof evcnt) != sizeof evcnt)
905: errx(1, "event chain trashed: %s", kvm_geterr(kd));
1.1 deraadt 906: if (strcmp(evcnt.ev_name, "intr") == 0) {
907: if (kvm_read(kd, (long)evcnt.ev_dev, (void *)&dev,
1.50 art 908: sizeof dev) != sizeof dev)
909: errx(1, "event chain trashed: %s", kvm_geterr(kd));
1.1 deraadt 910: if (evcnt.ev_count)
1.33 art 911: (void)printf("%-14s %12d %8ld\n", dev.dv_xname,
912: evcnt.ev_count, (long)(evcnt.ev_count / uptime));
1.1 deraadt 913: inttotal += evcnt.ev_count++;
914: }
1.9 deraadt 915: evptr = evcnt.ev_list.tqe_next;
1.1 deraadt 916: }
1.27 alex 917: (void)printf("Total %12ld %8ld\n", inttotal, inttotal / uptime);
1.1 deraadt 918: }
919: #endif
920:
921: /*
922: * These names are defined in <sys/malloc.h>.
923: */
924: char *kmemnames[] = INITKMEMNAMES;
925:
926: void
927: domem()
928: {
929: register struct kmembuckets *kp;
930: register struct kmemstats *ks;
931: register int i, j;
932: int len, size, first;
1.50 art 933: u_long totuse = 0, totfree = 0;
934: quad_t totreq = 0;
1.1 deraadt 935: char *name;
936: struct kmemstats kmemstats[M_LAST];
937: struct kmembuckets buckets[MINBUCKET + 16];
1.50 art 938: int mib[4];
939: size_t siz;
940: char buf[BUFSIZ], *bufp, *ap;
941:
942: if (memf == NULL && nlistf == NULL) {
943: mib[0] = CTL_KERN;
944: mib[1] = KERN_MALLOCSTATS;
945: mib[2] = KERN_MALLOC_BUCKETS;
946: siz = sizeof(buf);
947: if (sysctl(mib, 3, buf, &siz, NULL, 0) < 0) {
948: printf("Could not acquire information on kernel memory bucket sizes.\n");
949: return;
950: }
951:
952: bufp = buf;
953: mib[2] = KERN_MALLOC_BUCKET;
954: siz = sizeof(struct kmembuckets);
955: i = 0;
956: while ((ap = strsep(&bufp, ",")) != NULL) {
957: mib[3] = atoi(ap);
958:
959: if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz,
960: NULL, 0) < 0) {
961: printf("Failed to read statistics for bucket %d.\n", mib[3]);
962: return;
963: }
964: i++;
965: }
966: } else {
967: kread(X_KMEMBUCKETS, buckets, sizeof(buckets));
968: }
1.1 deraadt 969:
1.18 kstailey 970: for (first = 1, i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16;
971: i++, kp++) {
1.1 deraadt 972: if (kp->kb_calls == 0)
973: continue;
1.18 kstailey 974: if (first) {
975: (void)printf("Memory statistics by bucket size\n");
976: (void)printf(
1.50 art 977: " Size In Use Free Requests HighWater Couldfree\n");
1.18 kstailey 978: first = 0;
979: }
1.1 deraadt 980: size = 1 << i;
1.50 art 981: (void)printf("%8d %8qu %6qu %18qu %7qu %10qu\n", size,
1.1 deraadt 982: kp->kb_total - kp->kb_totalfree,
983: kp->kb_totalfree, kp->kb_calls,
984: kp->kb_highwat, kp->kb_couldfree);
985: totfree += size * kp->kb_totalfree;
1.18 kstailey 986: }
987:
988: /*
989: * If kmem statistics are not being gathered by the kernel,
990: * first will still be 1.
991: */
992: if (first) {
993: printf(
994: "Kmem statistics are not being gathered by the kernel.\n");
995: return;
1.1 deraadt 996: }
997:
1.52 ! angelos 998: if (memf == NULL && nlistf == NULL) {
! 999: bzero(kmemstats, sizeof(kmemstats));
! 1000: for (i = 0; i < M_LAST; i++) {
! 1001: mib[0] = CTL_KERN;
! 1002: mib[1] = KERN_MALLOCSTATS;
! 1003: mib[2] = KERN_MALLOC_KMEMSTATS;
! 1004: mib[3] = i;
! 1005: siz = sizeof(struct kmemstats);
! 1006:
! 1007: /*
! 1008: * Skip errors -- these are presumed to be unallocated
! 1009: * entries.
! 1010: */
! 1011: if (sysctl(mib, 4, &kmemstats[i], &siz, NULL, 0) < 0)
! 1012: continue;
! 1013: }
! 1014: } else {
! 1015: kread(X_KMEMSTAT, kmemstats, sizeof(kmemstats));
! 1016: }
! 1017:
1.1 deraadt 1018: (void)printf("\nMemory usage type by bucket size\n");
1019: (void)printf(" Size Type(s)\n");
1020: kp = &buckets[MINBUCKET];
1021: for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1, kp++) {
1022: if (kp->kb_calls == 0)
1023: continue;
1024: first = 1;
1025: len = 8;
1026: for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
1027: if (ks->ks_calls == 0)
1028: continue;
1029: if ((ks->ks_size & j) == 0)
1030: continue;
1031: name = kmemnames[i] ? kmemnames[i] : "undefined";
1032: len += 2 + strlen(name);
1033: if (first)
1034: printf("%8d %s", j, name);
1035: else
1036: printf(",");
1037: if (len >= 80) {
1038: printf("\n\t ");
1039: len = 10 + strlen(name);
1040: }
1041: if (!first)
1042: printf(" %s", name);
1043: first = 0;
1044: }
1045: printf("\n");
1046: }
1047:
1048: (void)printf(
1.26 deraadt 1049: "\nMemory statistics by type Type Kern\n");
1.1 deraadt 1050: (void)printf(
1.26 deraadt 1051: " Type InUse MemUse HighUse Limit Requests Limit Limit Size(s)\n");
1.1 deraadt 1052: for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
1053: if (ks->ks_calls == 0)
1054: continue;
1.24 mickey 1055: (void)printf("%14s%6ld%6ldK%7ldK%6ldK%9ld%5u%6u",
1.1 deraadt 1056: kmemnames[i] ? kmemnames[i] : "undefined",
1057: ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
1058: (ks->ks_maxused + 1023) / 1024,
1059: (ks->ks_limit + 1023) / 1024, ks->ks_calls,
1060: ks->ks_limblocks, ks->ks_mapblocks);
1061: first = 1;
1062: for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1) {
1063: if ((ks->ks_size & j) == 0)
1064: continue;
1065: if (first)
1066: printf(" %d", j);
1067: else
1068: printf(",%d", j);
1069: first = 0;