1 /* 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)vmstat.c 5.23 (Berkeley) 12/18/90"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 #include <sys/file.h> 20 #include <sys/vm.h> 21 #include <sys/dkstat.h> 22 #include <sys/buf.h> 23 #include <sys/namei.h> 24 #include <sys/text.h> 25 #include <sys/malloc.h> 26 #include <ctype.h> 27 #include <errno.h> 28 #include <kvm.h> 29 #include <nlist.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <paths.h> 34 35 struct nlist nl[] = { 36 #define X_CPTIME 0 37 { "_cp_time" }, 38 #define X_RATE 1 39 { "_rate" }, 40 #define X_TOTAL 2 41 { "_total" }, 42 #define X_DEFICIT 3 43 { "_deficit" }, 44 #define X_FORKSTAT 4 45 { "_forkstat" }, 46 #define X_SUM 5 47 { "_sum" }, 48 #define X_FIRSTFREE 6 49 { "_firstfree" }, 50 #define X_MAXFREE 7 51 { "_maxfree" }, 52 #define X_BOOTTIME 8 53 { "_boottime" }, 54 #define X_DKXFER 9 55 { "_dk_xfer" }, 56 #define X_REC 10 57 { "_rectime" }, 58 #define X_PGIN 11 59 { "_pgintime" }, 60 #define X_HZ 12 61 { "_hz" }, 62 #define X_PHZ 13 63 { "_phz" }, 64 #define X_NCHSTATS 14 65 { "_nchstats" }, 66 #define X_INTRNAMES 15 67 { "_intrnames" }, 68 #define X_EINTRNAMES 16 69 { "_eintrnames" }, 70 #define X_INTRCNT 17 71 { "_intrcnt" }, 72 #define X_EINTRCNT 18 73 { "_eintrcnt" }, 74 #define X_DK_NDRIVE 19 75 { "_dk_ndrive" }, 76 #define X_XSTATS 20 77 { "_xstats" }, 78 #define X_KMEMSTAT 21 79 { "_kmemstats" }, 80 #define X_KMEMBUCKETS 22 81 { "_bucket" }, 82 #define X_END 22 83 #ifdef vax 84 #define X_MBDINIT (X_END+1) 85 { "_mbdinit" }, 86 #define X_UBDINIT (X_END+2) 87 { "_ubdinit" }, 88 #endif 89 #ifdef tahoe 90 #define X_VBDINIT (X_END+1) 91 { "_vbdinit" }, 92 #define X_CKEYSTATS (X_END+2) 93 { "_ckeystats" }, 94 #define X_DKEYSTATS (X_END+3) 95 { "_dkeystats" }, 96 #endif 97 #ifdef hp300 98 #define X_HPDINIT (X_END+1) 99 { "_hp_dinit" }, 100 #endif 101 { "" }, 102 }; 103 104 char *vmunix = _PATH_UNIX; 105 char *kmem = NULL; 106 char **dr_name; 107 int *dr_select; 108 int dk_ndrive; 109 int ndrives = 0; 110 #ifdef vax 111 char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; 112 #else 113 #ifdef hp300 114 char *defdrives[] = { "rd0", "rd1", "rd2", 0 }; 115 #else 116 char *defdrives[] = { 0 }; 117 #endif 118 #endif 119 double stat1(); 120 int firstfree, maxfree; 121 int hz; 122 int phz; 123 int HZ; 124 125 struct { 126 int busy; 127 long time[CPUSTATES]; 128 long *xfer; 129 struct vmmeter Rate; 130 struct vmtotal Total; 131 struct vmmeter Sum; 132 struct forkstat Forkstat; 133 unsigned rectime; 134 unsigned pgintime; 135 } s, s1; 136 #define rate s.Rate 137 #define total s.Total 138 #define sum s.Sum 139 #define forkstat s.Forkstat 140 141 struct vmmeter osum; 142 int deficit; 143 double etime; 144 time_t now, boottime; 145 int lines = 1; 146 void printhdr(); 147 long lseek(); 148 149 #define INTS(x) ((x) - (hz + phz)) 150 151 #define FORKSTAT 0x01 152 #define INTRSTAT 0x02 153 #define MEMSTAT 0x04 154 #define SUMSTAT 0x08 155 #define TIMESTAT 0x10 156 #define VMSTAT 0x20 157 #define ZEROOUT 0x40 158 159 main(argc, argv) 160 register int argc; 161 register char **argv; 162 { 163 register int c, i, todo = 0; 164 extern int optind; 165 extern char *optarg; 166 167 while ((c = getopt(argc, argv, "fik:mstu:z")) != EOF) { 168 switch (c) { 169 case 'f': 170 todo |= FORKSTAT; 171 break; 172 case 'i': 173 todo |= INTRSTAT; 174 break; 175 case 'k': 176 kmem = optarg; 177 break; 178 case 'm': 179 todo |= MEMSTAT; 180 break; 181 case 's': 182 todo |= SUMSTAT; 183 break; 184 case 't': 185 todo |= TIMESTAT; 186 break; 187 case 'u': 188 vmunix = optarg; 189 break; 190 case 'z': 191 todo |= ZEROOUT; 192 break; 193 case '?': 194 usage(); 195 /* NOTREACHED */ 196 default: 197 (void) fprintf(stderr, 198 "vmstat: internal error in options\n"); 199 exit(1); 200 /* NOTREACHED */ 201 } 202 } 203 204 /* 205 * Zeroing the statistics is fundamentally different 206 * (and really belongs in a separate program). 207 */ 208 if (todo & ZEROOUT) { 209 if (todo & ~ZEROOUT || kmem) 210 usage(); 211 nl[0].n_name = nl[X_SUM].n_name; 212 nl[1].n_name = 0; 213 if (nlist(vmunix, nl) || nl[0].n_type == 0) { 214 (void) fprintf(stderr, 215 "vmstat: cannot get symbol %s from %s\n", 216 nl[0].n_name, vmunix); 217 exit(1); 218 } 219 if ((i = open(kmem = _PATH_KMEM, 2)) < 0) { 220 (void) fprintf(stderr, "vmstat: cannot write %s: %s\n", 221 kmem, strerror(errno)); 222 exit(1); 223 } 224 (void) lseek(i, (long)nl[0].n_value, L_SET); 225 if (write(i, (char *)&s.Sum, sizeof s.Sum) != sizeof s.Sum) { 226 (void) fprintf(stderr, "vmstat: write(%s): %s\n", 227 kmem, strerror(errno)); 228 exit(1); 229 } 230 exit(0); 231 } 232 233 if (todo == 0) 234 todo = VMSTAT; 235 236 if (kvm_openfiles(vmunix, kmem, (char *)NULL) < 0) { 237 (void) fprintf(stderr, 238 "vmstat: kvm_openfiles(%s, %s, NULL): %s\n", 239 vmunix, kmem ? kmem : "NULL", kvm_geterr()); 240 exit(1); 241 } 242 243 (void) kvm_nlist(nl); 244 if (nl[0].n_type == 0) { 245 (void) fprintf(stderr, "vmstat: %s: no namelist\n", 246 vmunix); 247 exit(1); 248 } 249 250 /* 251 * Fork, memory, sum, and time statistics do not need everything. 252 */ 253 if (todo & FORKSTAT) 254 doforkst(); 255 if (todo & MEMSTAT) 256 domem(); 257 if (todo & SUMSTAT) 258 dosum(); 259 if (todo & TIMESTAT) 260 dotimes(); 261 if (todo & INTRSTAT) 262 dointr(); 263 if (todo & VMSTAT) { 264 /* 265 * Read drive names, decide which drives to report, etc. 266 */ 267 argc -= optind; 268 argv += optind; 269 i = getdrivedata(argc, argv); 270 argc -= i; 271 argv += i; 272 dovmstat(argc > 0 ? atoi(argv[0]) : 0, 273 argc > 1 ? atoi(argv[1]) : 0); 274 } 275 exit(0); 276 } 277 278 usage() 279 { 280 281 (void) fprintf(stderr, 282 "usage: vmstat [-fimst]\n\tvmstat [drive-list] [interval [count]]\n\tvmstat -z\n"); 283 exit(1); 284 } 285 286 /* 287 * kread reads something from the kernel, given its nlist index. 288 */ 289 void 290 kread(nlx, addr, size) 291 int nlx; 292 char *addr; 293 size_t size; 294 { 295 char *sym; 296 297 if (nl[nlx].n_type == 0 || nl[nlx].n_value == 0) { 298 sym = nl[nlx].n_name; 299 if (*sym == '_') 300 sym++; 301 (void) fprintf(stderr, 302 "vmstat: symbol `%s' not defined in %s\n", sym, vmunix); 303 exit(1); 304 } 305 if (kvm_read(nl[nlx].n_value, addr, size) != size) { 306 sym = nl[nlx].n_name; 307 if (*sym == '_') 308 sym++; 309 (void) fprintf(stderr, 310 "vmstat: error reading `%s': %s\n", sym, kvm_geterr()); 311 exit(1); 312 } 313 } 314 315 getdrivedata(argc, argv) 316 int argc; 317 char **argv; 318 { 319 register int i; 320 register char **cp; 321 int ret; 322 char buf[30]; 323 324 kread(X_FIRSTFREE, (char *)&firstfree, sizeof firstfree); 325 kread(X_MAXFREE, (char *)&maxfree, sizeof maxfree); 326 kread(X_HZ, (char *)&hz, sizeof hz); 327 if (nl[X_PHZ].n_type != 0 && nl[X_PHZ].n_value != 0) 328 kread(X_PHZ, (char *)&phz, sizeof phz); 329 HZ = phz ? phz : hz; 330 kread(X_DK_NDRIVE, (char *)&dk_ndrive, sizeof dk_ndrive); 331 if (dk_ndrive <= 0) { 332 (void) fprintf(stderr, "vmstat: dk_ndrive %d\n", dk_ndrive); 333 exit(1); 334 } 335 dr_select = (int *)calloc((size_t)dk_ndrive, sizeof (int)); 336 dr_name = (char **)malloc((size_t)dk_ndrive * sizeof (char *)); 337 for (i = 0; i < dk_ndrive; i++) 338 dr_name[i] = NULL; 339 s.xfer = (long *)calloc((size_t)dk_ndrive, sizeof (long)); 340 s1.xfer = (long *)calloc((size_t)dk_ndrive, sizeof (long)); 341 read_names(); 342 for (i = 0; i < dk_ndrive; i++) { 343 if (dr_name[i] == NULL) { 344 (void) sprintf(buf, "??%d", i); 345 dr_name[i] = strdup(buf); 346 } 347 } 348 349 /* 350 * Choose drives to be displayed. Priority 351 * goes to (in order) drives supplied as arguments, 352 * default drives. If everything isn't filled 353 * in and there are drives not taken care of, 354 * display the first few that fit. 355 */ 356 ret = 0; 357 ndrives = 0; 358 while (argc > 0 && !isdigit(argv[0][0])) { 359 for (i = 0; i < dk_ndrive; i++) { 360 if (strcmp(dr_name[i], argv[0])) 361 continue; 362 dr_select[i] = 1; 363 ndrives++; 364 break; 365 } 366 ret++; 367 argc--, argv++; 368 } 369 for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 370 if (dr_select[i]) 371 continue; 372 for (cp = defdrives; *cp; cp++) 373 if (strcmp(dr_name[i], *cp) == 0) { 374 dr_select[i] = 1; 375 ndrives++; 376 break; 377 } 378 } 379 for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 380 if (dr_select[i]) 381 continue; 382 dr_select[i] = 1; 383 ndrives++; 384 } 385 return (ret); 386 } 387 388 long 389 getuptime() 390 { 391 time_t time(); 392 long uptime; 393 394 if (boottime == 0) 395 kread(X_BOOTTIME, (char *)&boottime, sizeof boottime); 396 (void) time(&now); 397 uptime = now - boottime; 398 if (uptime <= 0 || uptime > 60*60*24*365*10) { 399 (void) fprintf(stderr, 400 "vmstat: time makes no sense; namelist must be wrong.\n"); 401 exit(1); 402 } 403 return (uptime); 404 } 405 406 dovmstat(sleeptime, iter) 407 int sleeptime, iter; 408 { 409 register int i; 410 long interval, t; 411 412 interval = getuptime(); 413 (void) signal(SIGCONT, printhdr); 414 loop: 415 if (--lines == 0) 416 printhdr(); 417 kread(X_CPTIME, (char *)s.time, sizeof s.time); 418 kread(X_DKXFER, (char *)s.xfer, sizeof *s.xfer * dk_ndrive); 419 if (interval != 1) 420 kread(X_SUM, (char *)&rate, sizeof rate); 421 else 422 kread(X_RATE, (char *)&rate, sizeof rate); 423 kread(X_TOTAL, (char *)&total, sizeof total); 424 osum = sum; 425 kread(X_SUM, (char *)&sum, sizeof sum); 426 kread(X_DEFICIT, (char *)&deficit, sizeof deficit); 427 etime = 0; 428 for (i = 0; i < dk_ndrive; i++) { 429 t = s.xfer[i]; 430 s.xfer[i] -= s1.xfer[i]; 431 s1.xfer[i] = t; 432 } 433 for (i = 0; i < CPUSTATES; i++) { 434 t = s.time[i]; 435 s.time[i] -= s1.time[i]; 436 s1.time[i] = t; 437 etime += s.time[i]; 438 } 439 if (etime == 0.) 440 etime = 1.; 441 (void) printf("%2d%2d%2d", 442 total.t_rq, total.t_dw + total.t_pw, total.t_sw); 443 #define pgtok(a) ((a)*NBPG >> 10) 444 (void) printf("%6ld%6ld", pgtok(total.t_avm), pgtok(total.t_free)); 445 (void) printf("%4lu%3lu", 446 (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec)) / interval, 447 (rate.v_xsfrec+rate.v_xifrec) / interval); 448 (void) printf("%4lu", pgtok(rate.v_pgpgin) / interval); 449 (void) printf("%4lu%4lu%4d%4lu", pgtok(rate.v_pgpgout) / interval, 450 pgtok(rate.v_dfree) / interval, 451 pgtok(deficit), rate.v_scan / interval); 452 etime /= (float)HZ; 453 for (i = 0; i < dk_ndrive; i++) 454 if (dr_select[i]) 455 stats(i); 456 (void) printf("%4lu%4lu%4lu", INTS(rate.v_intr / interval), 457 rate.v_syscall / interval, rate.v_swtch / interval); 458 for(i = 0; i < CPUSTATES; i++) { 459 float f = stat1(i); 460 if (i == 0) { /* US+NI */ 461 i++; 462 f += stat1(i); 463 } 464 (void) printf("%3.0f", f); 465 } 466 (void) printf("\n"); 467 (void) fflush(stdout); 468 interval = 1; 469 if (iter && --iter == 0) 470 return; 471 if (sleeptime) { 472 sleep((unsigned)sleeptime); 473 goto loop; 474 } 475 } 476 477 void 478 printhdr() 479 { 480 register int i, j; 481 482 (void) printf(" procs memory page "); 483 i = (ndrives * 3 - 6) / 2; 484 if (i < 0) 485 i = 0; 486 for (j = 0; j < i; j++) 487 (void) putchar(' '); 488 (void) printf("faults"); 489 i = ndrives * 3 - 6 - i; 490 for (j = 0; j < i; j++) 491 (void) putchar(' '); 492 (void) printf(" cpu\n"); 493 (void) printf(" r b w avm fre re at pi po fr de sr "); 494 for (i = 0; i < dk_ndrive; i++) 495 if (dr_select[i]) 496 (void) printf("%c%c ", dr_name[i][0], 497 dr_name[i][strlen(dr_name[i]) - 1]); 498 (void) printf(" in sy cs us sy id\n"); 499 lines = 19; 500 } 501 502 dotimes() 503 { 504 505 kread(X_REC, (char *)&s.rectime, sizeof s.rectime); 506 kread(X_PGIN, (char *)&s.pgintime, sizeof s.pgintime); 507 kread(X_SUM, (char *)&sum, sizeof sum); 508 (void) printf("%u reclaims, %u total time (usec)\n", 509 sum.v_pgrec, s.rectime); 510 (void) printf("average: %u usec / reclaim\n", s.rectime / sum.v_pgrec); 511 (void) printf("\n"); 512 (void) printf("%u page ins, %u total time (msec)\n", 513 sum.v_pgin, s.pgintime / 10); 514 (void) printf("average: %8.1f msec / page in\n", 515 s.pgintime / (sum.v_pgin * 10.0)); 516 } 517 518 pct(top, bot) 519 long top, bot; 520 { 521 522 if (bot == 0) 523 return (0); 524 return ((top * 100) / bot); 525 } 526 527 #define PCT(top, bot) pct((long)(top), (long)(bot)) 528 529 #if defined(tahoe) 530 #include <machine/cpu.h> 531 #endif 532 533 dosum() 534 { 535 struct nchstats nchstats; 536 struct xstats xstats; 537 long nchtotal; 538 #if defined(tahoe) 539 struct keystats keystats; 540 #endif 541 542 kread(X_SUM, (char *)&sum, sizeof sum); 543 (void) printf("%9u swap ins\n", sum.v_swpin); 544 (void) printf("%9u swap outs\n", sum.v_swpout); 545 (void) printf("%9u pages swapped in\n", sum.v_pswpin / CLSIZE); 546 (void) printf("%9u pages swapped out\n", sum.v_pswpout / CLSIZE); 547 (void) printf("%9u total address trans. faults taken\n", sum.v_faults); 548 (void) printf("%9u page ins\n", sum.v_pgin); 549 (void) printf("%9u page outs\n", sum.v_pgout); 550 (void) printf("%9u pages paged in\n", sum.v_pgpgin); 551 (void) printf("%9u pages paged out\n", sum.v_pgpgout); 552 (void) printf("%9u sequential process pages freed\n", sum.v_seqfree); 553 (void) printf("%9u total reclaims (%d%% fast)\n", sum.v_pgrec, 554 PCT(sum.v_fastpgrec, sum.v_pgrec)); 555 (void) printf("%9u reclaims from free list\n", sum.v_pgfrec); 556 (void) printf("%9u intransit blocking page faults\n", sum.v_intrans); 557 (void) printf("%9u zero fill pages created\n", sum.v_nzfod / CLSIZE); 558 (void) printf("%9u zero fill page faults\n", sum.v_zfod / CLSIZE); 559 (void) printf("%9u executable fill pages created\n", 560 sum.v_nexfod / CLSIZE); 561 (void) printf("%9u executable fill page faults\n", 562 sum.v_exfod / CLSIZE); 563 (void) printf("%9u swap text pages found in free list\n", 564 sum.v_xsfrec); 565 (void) printf("%9u inode text pages found in free list\n", 566 sum.v_xifrec); 567 (void) printf("%9u file fill pages created\n", sum.v_nvrfod / CLSIZE); 568 (void) printf("%9u file fill page faults\n", sum.v_vrfod / CLSIZE); 569 (void) printf("%9u pages examined by the clock daemon\n", sum.v_scan); 570 (void) printf("%9u revolutions of the clock hand\n", sum.v_rev); 571 (void) printf("%9u pages freed by the clock daemon\n", 572 sum.v_dfree / CLSIZE); 573 (void) printf("%9u cpu context switches\n", sum.v_swtch); 574 (void) printf("%9u device interrupts\n", sum.v_intr); 575 (void) printf("%9u software interrupts\n", sum.v_soft); 576 #ifdef vax 577 (void) printf("%9u pseudo-dma dz interrupts\n", sum.v_pdma); 578 #endif 579 (void) printf("%9u traps\n", sum.v_trap); 580 (void) printf("%9u system calls\n", sum.v_syscall); 581 kread(X_NCHSTATS, (char *)&nchstats, sizeof nchstats); 582 nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits + 583 nchstats.ncs_badhits + nchstats.ncs_falsehits + 584 nchstats.ncs_miss + nchstats.ncs_long; 585 (void) printf("%9ld total name lookups\n", nchtotal); 586 (void) printf( 587 "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n", 588 "", PCT(nchstats.ncs_goodhits, nchtotal), 589 PCT(nchstats.ncs_neghits, nchtotal), 590 PCT(nchstats.ncs_pass2, nchtotal)); 591 (void) printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "", 592 PCT(nchstats.ncs_badhits, nchtotal), 593 PCT(nchstats.ncs_falsehits, nchtotal), 594 PCT(nchstats.ncs_long, nchtotal)); 595 kread(X_XSTATS, (char *)&xstats, sizeof xstats); 596 (void) printf("%9lu total calls to xalloc (cache hits %d%%)\n", 597 xstats.alloc, PCT(xstats.alloc_cachehit, xstats.alloc)); 598 (void) printf("%9s sticky %lu flushed %lu unused %lu\n", "", 599 xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused); 600 (void) printf("%9lu total calls to xfree", xstats.free); 601 (void) printf(" (sticky %lu cached %lu swapped %lu)\n", 602 xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap); 603 #if defined(tahoe) 604 kread(X_CKEYSTATS, (char *)&keystats, sizeof keystats); 605 (void) printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 606 keystats.ks_allocs, "code cache keys allocated", 607 PCT(keystats.ks_allocfree, keystats.ks_allocs), 608 PCT(keystats.ks_norefs, keystats.ks_allocs), 609 PCT(keystats.ks_taken, keystats.ks_allocs), 610 PCT(keystats.ks_shared, keystats.ks_allocs)); 611 kread(X_DKEYSTATS, (char *)&keystats, sizeof keystats); 612 (void) printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 613 keystats.ks_allocs, "data cache keys allocated", 614 PCT(keystats.ks_allocfree, keystats.ks_allocs), 615 PCT(keystats.ks_norefs, keystats.ks_allocs), 616 PCT(keystats.ks_taken, keystats.ks_allocs), 617 PCT(keystats.ks_shared, keystats.ks_allocs)); 618 #endif 619 } 620 621 doforkst() 622 { 623 624 kread(X_FORKSTAT, (char *)&forkstat, sizeof forkstat); 625 (void) printf("%d forks, %d pages, average=%.2f\n", 626 forkstat.cntfork, forkstat.sizfork, 627 (float) forkstat.sizfork / forkstat.cntfork); 628 (void) printf("%d vforks, %d pages, average=%.2f\n", 629 forkstat.cntvfork, forkstat.sizvfork, 630 (float)forkstat.sizvfork / forkstat.cntvfork); 631 } 632 633 stats(dn) 634 { 635 636 if (dn >= dk_ndrive) { 637 (void) printf(" 0"); 638 return; 639 } 640 (void) printf("%3.0f", s.xfer[dn]/etime); 641 } 642 643 double 644 stat1(row) 645 { 646 double t; 647 register i; 648 649 t = 0; 650 for(i=0; i<CPUSTATES; i++) 651 t += s.time[i]; 652 if(t == 0.) 653 t = 1.; 654 return(s.time[row]*100./t); 655 } 656 657 dointr() 658 { 659 register int nintr, inamlen; 660 register long *intrcnt, inttotal, uptime = getuptime(); 661 register char *intrname; 662 663 nintr = nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value; 664 inamlen = nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value; 665 intrcnt = (long *)malloc((size_t)nintr); 666 intrname = malloc((size_t)inamlen); 667 if (intrcnt == NULL || intrname == NULL) { 668 (void) fprintf(stderr, "vmstat: %s.\n", strerror(errno)); 669 exit(9); 670 } 671 kread(X_INTRCNT, (char *)intrcnt, (size_t)nintr); 672 kread(X_INTRNAMES, intrname, (size_t)inamlen); 673 (void) printf("interrupt total rate\n"); 674 inttotal = 0; 675 nintr /= sizeof(long); 676 while (--nintr >= 0) { 677 if (*intrcnt) 678 (void) printf("%-12s %8ld %8ld\n", intrname, 679 *intrcnt, *intrcnt / uptime); 680 intrname += strlen(intrname) + 1; 681 inttotal += *intrcnt++; 682 } 683 (void) printf("Total %8ld %8ld\n", inttotal, inttotal / uptime); 684 } 685 686 /* 687 * These names are defined in <sys/malloc.h>. 688 */ 689 char *kmemnames[] = INITKMEMNAMES; 690 691 domem() 692 { 693 register struct kmembuckets *kp; 694 register struct kmemstats *ks; 695 register int i; 696 struct kmemstats kmemstats[M_LAST]; 697 struct kmembuckets buckets[MINBUCKET + 16]; 698 699 kread(X_KMEMBUCKETS, (char *)buckets, sizeof buckets); 700 (void) printf("Memory statistics by bucket size\n"); 701 (void) printf( 702 " Size In Use Free Requests HighWater Couldfree\n"); 703 for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) { 704 if (kp->kb_calls == 0) 705 continue; 706 (void) printf("%8d%9ld%7ld%11ld%8ld%11ld\n", 1 << i, 707 kp->kb_total - kp->kb_totalfree, 708 kp->kb_totalfree, kp->kb_calls, 709 kp->kb_highwat, kp->kb_couldfree); 710 711 } 712 kread(X_KMEMSTAT, (char *)kmemstats, sizeof kmemstats); 713 (void) printf("Memory statistics by type\n"); 714 (void) printf("\ 715 Type In Use MemUse HighUse Limit Requests TypeLimit KernLimit\n"); 716 for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) { 717 if (ks->ks_calls == 0) 718 continue; 719 (void) printf("%10s%7ld%8ldK%9ldK%6ldK%9ld%7u%10u\n", 720 kmemnames[i] ? kmemnames[i] : "undefined", 721 ks->ks_inuse, (ks->ks_memuse + 1023) / 1024, 722 (ks->ks_maxused + 1023) / 1024, 723 (ks->ks_limit + 1023) / 1024, ks->ks_calls, 724 ks->ks_limblocks, ks->ks_mapblocks); 725 } 726 } 727 728 /* 729 * Read the drive names out of kmem. 730 */ 731 #ifdef vax 732 #include <uba/ubavar.h> 733 #include <mba/mbavar.h> 734 735 read_names() 736 { 737 register char *p; 738 unsigned long mp, up; 739 struct mba_device mdev; 740 struct mba_driver mdrv; 741 struct uba_device udev; 742 struct uba_driver udrv; 743 char name[10]; 744 static char buf[BUFSIZ]; 745 746 mp = nl[X_MBDINIT].n_value; 747 up = nl[X_UBDINIT].n_value; 748 if (mp == 0 && up == 0) { 749 (void) fprintf(stderr, 750 "vmstat: disk init info not in namelist\n"); 751 exit(1); 752 } 753 p = buf; 754 if (mp) for (;; mp += sizeof mdev) { 755 (void) kvm_read((u_long)mp, (char *)&mdev, sizeof mdev); 756 if (mdev.mi_driver == 0) 757 break; 758 if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 759 continue; 760 (void) kvm_read((u_long)mdev.mi_driver, 761 (char *)&mdrv, sizeof mdrv); 762 (void) kvm_read((u_long)mdrv.md_dname, name, sizeof name); 763 dr_name[mdev.mi_dk] = p; 764 p += sprintf(p, "%s%d", name, mdev.mi_unit); 765 } 766 if (up) for (;; up += sizeof udev) { 767 (void) kvm_read(up, (char *)&udev, sizeof udev); 768 if (udev.ui_driver == 0) 769 break; 770 if (udev.ui_dk < 0 || udev.ui_alive == 0) 771 continue; 772 (void) kvm_read((u_long)udev.ui_driver, 773 (char *)&udrv, sizeof udrv); 774 (void) kvm_read((u_long)udrv.ud_dname, name, sizeof name); 775 dr_name[udev.ui_dk] = p; 776 p += sprintf(p, "%s%d", name, udev.ui_unit); 777 } 778 } 779 #endif 780 781 #ifdef tahoe 782 #include <vba/vbavar.h> 783 784 /* 785 * Read the drive names out of kmem. 786 */ 787 read_names() 788 { 789 register char *p; 790 struct vba_device udev, *up; 791 struct vba_driver udrv; 792 char name[10]; 793 static char buf[BUFSIZ]; 794 795 up = (struct vba_device *) nl[X_VBDINIT].n_value; 796 if (up == 0) { 797 (void) fprintf(stderr, 798 "vmstat: disk init info not in namelist\n"); 799 exit(1); 800 } 801 p = buf; 802 for (;; up += sizeof udev) { 803 (void) kvm_read(up, (char *)&udev, sizeof udev); 804 if (udev.ui_driver == 0) 805 break; 806 if (udev.ui_dk < 0 || udev.ui_alive == 0) 807 continue; 808 (void) kvm_read((u_long)udev.ui_driver, 809 (char *)&udrv, sizeof udrv); 810 (void) kvm_read((u_long)udrv.ud_dname, name, sizeof name); 811 dr_name[udev.ui_dk] = p; 812 p += sprintf(p, "%s%d", name, udev.ui_unit); 813 } 814 } 815 #endif 816 817 #ifdef hp300 818 #include <hpdev/device.h> 819 820 read_names() 821 { 822 register char *p; 823 register u_long hp; 824 struct hp_device hdev; 825 struct driver hdrv; 826 static char buf[BUFSIZ]; 827 828 hp = nl[X_HPDINIT].n_value; 829 if (hp == 0) { 830 (void) fprintf(stderr, 831 "vmstat: disk init info not in namelist\n"); 832 exit(1); 833 } 834 p = buf; 835 for (;; hp += sizeof hdev) { 836 (void) kvm_read(hp, (char *)&hdev, sizeof hdev); 837 if (hdev.hp_driver == 0) 838 break; 839 if (hdev.hp_dk < 0 || hdev.hp_alive == 0) 840 continue; 841 (void) kvm_read((u_long)hdev.hp_driver, 842 (char *)&hdrv, sizeof hdrv); 843 (void) kvm_read((u_long)hdrv.d_name, name, sizeof name); 844 dr_name[hdev.hp_dk] = p; 845 p += sprintf(p, "%s%d", name, hdev.hp_unit); 846 } 847 } 848 #endif 849