[BACK]Return to vmstat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vmstat

Diff for /src/usr.bin/vmstat/vmstat.c between version 1.47 and 1.48

version 1.47, 2001/01/04 17:40:26 version 1.48, 2001/03/21 23:51:47
Line 48 
Line 48 
 #endif  #endif
 #endif /* not lint */  #endif /* not lint */
   
   #define __POOL_EXPOSE
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/proc.h>  #include <sys/proc.h>
Line 60 
Line 62 
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
 #include <sys/device.h>  #include <sys/device.h>
   #include <sys/pool.h>
 #include <vm/vm.h>  #include <vm/vm.h>
 #include <time.h>  #include <time.h>
 #include <nlist.h>  #include <nlist.h>
Line 114 
Line 117 
         { "_allevents" },          { "_allevents" },
 #define X_FORKSTAT      13  #define X_FORKSTAT      13
         { "_forkstat" },          { "_forkstat" },
 #define X_NSELCOLL      14  #define X_POOLHEAD      14
         { "_nselcoll" },          { "_pool_head" },
 #define X_END           15  #define X_END           15
 #if defined(__pc532__)  #if defined(__pc532__)
 #define X_IVT           (X_END)  #define X_IVT           (X_END)
Line 157 
Line 160 
 void    dkstats __P((void));  void    dkstats __P((void));
 void    dointr __P((void));  void    dointr __P((void));
 void    domem __P((void));  void    domem __P((void));
   void    dopool __P((void));
 void    dosum __P((void));  void    dosum __P((void));
 void    dovmstat __P((u_int, int));  void    dovmstat __P((u_int, int));
 void    kread __P((int, void *, size_t));  void    kread __P((int, void *, size_t));
Line 170 
Line 174 
 /* Namelist and memory file names. */  /* Namelist and memory file names. */
 char    *nlistf, *memf;  char    *nlistf, *memf;
   
 extern char *__progname;  
   
 int  int
 main(argc, argv)  main(argc, argv)
         register int argc;          register int argc;
Line 236 
Line 238 
         }          }
   
         kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);          kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
         if (kd == 0)          if (kd == 0) {
                 errx(1, "kvm_openfiles: %s", errbuf);                  (void)fprintf(stderr,
                       "vmstat: kvm_openfiles: %s\n", errbuf);
                   exit(1);
           }
   
         if ((c = kvm_nlist(kd, namelist)) != 0) {          if ((c = kvm_nlist(kd, namelist)) != 0) {
   
Line 246 
Line 251 
   
                 if (c > 0) {                  if (c > 0) {
                         (void)fprintf(stderr,                          (void)fprintf(stderr,
                             "%s: undefined symbols:", __progname);                              "vmstat: undefined symbols:");
                         for (c = 0;                          for (c = 0;
                             c < sizeof(namelist)/sizeof(namelist[0]); c++)                              c < sizeof(namelist)/sizeof(namelist[0]); c++)
                                 if (namelist[c].n_type == 0)                                  if (namelist[c].n_type == 0)
                                         fprintf(stderr, " %s",                                          fprintf(stderr, " %s",
                                             namelist[c].n_name);                                              namelist[c].n_name);
                         (void)fputc('\n', stderr);                          (void)fputc('\n', stderr);
                         exit(1);  
                 } else                  } else
                         errx(1, "kvm_nlist: %s", kvm_geterr(kd));                          (void)fprintf(stderr, "vmstat: kvm_nlist: %s\n",
                               kvm_geterr(kd));
                   exit(1);
         }          }
   
         if (todo & VMSTAT) {          if (todo & VMSTAT) {
Line 290 
Line 296 
   
         if (todo & FORKSTAT)          if (todo & FORKSTAT)
                 doforkst();                  doforkst();
         if (todo & MEMSTAT)          if (todo & MEMSTAT) {
                 domem();                  domem();
                   dopool();
           }
         if (todo & SUMSTAT)          if (todo & SUMSTAT)
                 dosum();                  dosum();
         if (todo & TIMESTAT)          if (todo & TIMESTAT)
Line 344 
Line 352 
         static time_t now;          static time_t now;
         static struct timeval boottime;          static struct timeval boottime;
         time_t uptime;          time_t uptime;
         int mib[2];  
         size_t size;  
   
         if (boottime.tv_sec == 0) {          if (boottime.tv_sec == 0)
                 if (nlist == NULL && memf == NULL) {                  kread(X_BOOTTIME, &boottime, sizeof(boottime));
                         kread(X_BOOTTIME, &boottime, sizeof(boottime));  
                 } else {  
                         size = sizeof(boottime);  
                         mib[0] = CTL_KERN;  
                         mib[1] = KERN_BOOTTIME;  
                         if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) {  
                                 printf("Can't get kerninfo: %s\n",  
                                        strerror(errno));  
                                 bzero(&boottime, sizeof(boottime));  
                         }  
                 }  
         }  
         (void)time(&now);          (void)time(&now);
         uptime = now - boottime.tv_sec;          uptime = now - boottime.tv_sec;
         if (uptime <= 0 || uptime > 60*60*24*365*10)          if (uptime <= 0 || uptime > 60*60*24*365*10) {
                 errx(1, "time makes no sense; namelist must be wrong");                  (void)fprintf(stderr,
                       "vmstat: time makes no sense; namelist must be wrong.\n");
                   exit(1);
           }
         return(uptime);          return(uptime);
 }  }
   
Line 379 
Line 376 
         time_t uptime, halfuptime;          time_t uptime, halfuptime;
         void needhdr();          void needhdr();
         int mib[2];          int mib[2];
         struct clockinfo clkinfo;  
         size_t size;          size_t size;
   
         uptime = getuptime();          uptime = getuptime();
         halfuptime = uptime / 2;          halfuptime = uptime / 2;
         (void)signal(SIGCONT, needhdr);          (void)signal(SIGCONT, needhdr);
   
         mib[0] = CTL_KERN;          if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0)
         mib[1] = KERN_CLOCKRATE;                  kread(X_STATHZ, &hz, sizeof(hz));
         size = sizeof(clkinfo);          if (!hz)
         if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) {                  kread(X_HZ, &hz, sizeof(hz));
                 printf("Can't get kerninfo: %s\n", strerror(errno));  
                 return;  
         }  
         hz = clkinfo.stathz;  
   
         for (hdrcnt = 1;;) {          for (hdrcnt = 1;;) {
                 if (!--hdrcnt)                  if (!--hdrcnt)
Line 550 
Line 542 
 {  {
         struct nchstats nchstats;          struct nchstats nchstats;
         long nchtotal;          long nchtotal;
         int nselcoll;  
   
 #ifdef UVM  #ifdef UVM
         kread(X_UVMEXP, &uvmexp, sizeof(uvmexp));          kread(X_UVMEXP, &uvmexp, sizeof(uvmexp));
Line 565 
Line 556 
         (void)printf("%11u pages being paged out\n", uvmexp.paging);          (void)printf("%11u pages being paged out\n", uvmexp.paging);
         (void)printf("%11u pages wired\n", uvmexp.wired);          (void)printf("%11u pages wired\n", uvmexp.wired);
         (void)printf("%11u pages reserved for pagedaemon\n",          (void)printf("%11u pages reserved for pagedaemon\n",
             uvmexp.reserve_pagedaemon);                       uvmexp.reserve_pagedaemon);
         (void)printf("%11u pages reserved for kernel\n",          (void)printf("%11u pages reserved for kernel\n",
             uvmexp.reserve_kernel);                       uvmexp.reserve_kernel);
   
         /* swap */          /* swap */
         (void)printf("%11u swap pages\n", uvmexp.swpages);          (void)printf("%11u swap pages\n", uvmexp.swpages);
Line 587 
Line 578 
         (void)printf("%11u swap outs\n", uvmexp.swapouts);          (void)printf("%11u swap outs\n", uvmexp.swapouts);
         (void)printf("%11u forks\n", uvmexp.forks);          (void)printf("%11u forks\n", uvmexp.forks);
         (void)printf("%11u forks where vmspace is shared\n",          (void)printf("%11u forks where vmspace is shared\n",
             uvmexp.forks_sharevm);                       uvmexp.forks_sharevm);
   
         /* daemon counters */          /* daemon counters */
         (void)printf("%11u number of times the pagedeamon woke up\n",          (void)printf("%11u number of times the pagedeamon woke up\n",
             uvmexp.pdwoke);                       uvmexp.pdwoke);
         (void)printf("%11u revolutions of the clock hand\n", uvmexp.pdrevs);          (void)printf("%11u revolutions of the clock hand\n", uvmexp.pdrevs);
         (void)printf("%11u pages freed by pagedaemon\n", uvmexp.pdfreed);          (void)printf("%11u pages freed by pagedaemon\n", uvmexp.pdfreed);
         (void)printf("%11u pages scanned by pagedaemon\n", uvmexp.pdscans);          (void)printf("%11u pages scanned by pagedaemon\n", uvmexp.pdscans);
Line 646 
Line 637 
             PCT(nchstats.ncs_badhits, nchtotal),              PCT(nchstats.ncs_badhits, nchtotal),
             PCT(nchstats.ncs_falsehits, nchtotal),              PCT(nchstats.ncs_falsehits, nchtotal),
             PCT(nchstats.ncs_long, nchtotal));              PCT(nchstats.ncs_long, nchtotal));
         kread(X_NSELCOLL, &nselcoll, sizeof(nselcoll));  
         (void)printf("%11d select collisions\n", nselcoll);  
 }  }
   
 void  void
Line 730 
Line 719 
                 for (j = 0; j < 16; j++, ivp++) {                  for (j = 0; j < 16; j++, ivp++) {
                         if (ivp->iv_vec && ivp->iv_use && ivp->iv_cnt) {                          if (ivp->iv_vec && ivp->iv_use && ivp->iv_cnt) {
                                 if (kvm_read(kd, (u_long)ivp->iv_use, iname, 63) != 63) {                                  if (kvm_read(kd, (u_long)ivp->iv_use, iname, 63) != 63) {
                                         errx(1, "iv_use: %s", kvm_geterr(kd));                                          (void)fprintf(stderr, "vmstat: iv_use: %s\n",
                                             kvm_geterr(kd));                                              kvm_geterr(kd));
                                         exit(1);                                          exit(1);
                                 }                                  }
Line 752 
Line 741 
 dointr()  dointr()
 {  {
         struct intrhand *intrhand[16], *ihp, ih;          struct intrhand *intrhand[16], *ihp, ih;
         u_long inttotal;          long inttotal;
         time_t uptime;          time_t uptime;
         u_long intrstray[16];          int intrstray[16];
         char iname[17], fname[31];          char iname[17], fname[31];
         int i;          int i;
   
Line 773 
Line 762 
                         if (kvm_read(kd, (u_long)ih.ih_what, iname, 16) != 16)                          if (kvm_read(kd, (u_long)ih.ih_what, iname, 16) != 16)
                                 errx(1, "vmstat: ih_what: %s", kvm_geterr(kd));                                  errx(1, "vmstat: ih_what: %s", kvm_geterr(kd));
                         snprintf(fname, sizeof fname, "irq%d/%s", i, iname);                          snprintf(fname, sizeof fname, "irq%d/%s", i, iname);
                         printf("%-16.16s %10lu %8lu\n", fname, ih.ih_count,                          printf("%-16.16s %10ld %8ld\n", fname, ih.ih_count,
                             ih.ih_count / uptime);                              ih.ih_count / uptime);
                         inttotal += ih.ih_count;                          inttotal += ih.ih_count;
                         ihp = ih.ih_next;                          ihp = ih.ih_next;
Line 781 
Line 770 
         }          }
         for (i = 0; i < 16; i++)          for (i = 0; i < 16; i++)
                 if (intrstray[i]) {                  if (intrstray[i]) {
                         printf("Stray irq %-2d     %10lu %8lu\n",                          printf("Stray irq %-2d     %10d %8d\n",
                                i, intrstray[i], intrstray[i] / uptime);                                 i, intrstray[i], intrstray[i] / uptime);
                         inttotal += intrstray[i];                          inttotal += intrstray[i];
                 }                  }
         printf("Total            %10lu %8lu\n", inttotal, inttotal / uptime);          printf("Total            %10ld %8ld\n", inttotal, inttotal / uptime);
 }  }
 #else  #else
 void  void
Line 805 
Line 794 
             namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;              namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;
         intrcnt = malloc((size_t)nintr);          intrcnt = malloc((size_t)nintr);
         intrname = malloc((size_t)inamlen);          intrname = malloc((size_t)inamlen);
         if (intrcnt == NULL || intrname == NULL)          if (intrcnt == NULL || intrname == NULL) {
                 err(1, "malloc");                  (void)fprintf(stderr, "vmstat: %s.\n", strerror(errno));
                   exit(1);
           }
         kread(X_INTRCNT, intrcnt, (size_t)nintr);          kread(X_INTRCNT, intrcnt, (size_t)nintr);
         kread(X_INTRNAMES, intrname, (size_t)inamlen);          kread(X_INTRNAMES, intrname, (size_t)inamlen);
         (void)printf("interrupt             total     rate\n");          (void)printf("interrupt             total     rate\n");
Line 823 
Line 814 
         evptr = allevents.tqh_first;          evptr = allevents.tqh_first;
         while (evptr) {          while (evptr) {
                 if (kvm_read(kd, (long)evptr, (void *)&evcnt,                  if (kvm_read(kd, (long)evptr, (void *)&evcnt,
                     sizeof evcnt) != sizeof evcnt)                      sizeof evcnt) != sizeof evcnt) {
                         errx(1, "event chain trashed: %s", kvm_geterr(kd));                          (void)fprintf(stderr, "vmstat: event chain trashed: %s\n",
                               kvm_geterr(kd));
                           exit(1);
                   }
                 if (strcmp(evcnt.ev_name, "intr") == 0) {                  if (strcmp(evcnt.ev_name, "intr") == 0) {
                         if (kvm_read(kd, (long)evcnt.ev_dev, (void *)&dev,                          if (kvm_read(kd, (long)evcnt.ev_dev, (void *)&dev,
                             sizeof dev) != sizeof dev)                              sizeof dev) != sizeof dev) {
                                 errx(1, "event chain trashed: %s", kvm_geterr(kd));                                  (void)fprintf(stderr, "vmstat: event chain trashed: %s\n",
                                       kvm_geterr(kd));
                                   exit(1);
                           }
                         if (evcnt.ev_count)                          if (evcnt.ev_count)
                                 (void)printf("%-14s %12d %8ld\n", dev.dv_xname,                                  (void)printf("%-14s %12d %8ld\n", dev.dv_xname,
                                     evcnt.ev_count, (long)(evcnt.ev_count / uptime));                                      evcnt.ev_count, (long)(evcnt.ev_count / uptime));
Line 852 
Line 849 
         register struct kmemstats *ks;          register struct kmemstats *ks;
         register int i, j;          register int i, j;
         int len, size, first;          int len, size, first;
         u_long totuse = 0, totfree = 0;          long totuse = 0, totfree = 0, totreq = 0;
         quad_t totreq = 0;  
         char *name;          char *name;
         struct kmemstats kmemstats[M_LAST];          struct kmemstats kmemstats[M_LAST];
         struct kmembuckets buckets[MINBUCKET + 16];          struct kmembuckets buckets[MINBUCKET + 16];
         int mib[4];  
         size_t siz;  
         char buf[BUFSIZ], *bufp, *ap;  
   
         if (memf == NULL && nlistf == NULL) {          kread(X_KMEMBUCKETS, buckets, sizeof(buckets));
                 mib[0] = CTL_KERN;  
                 mib[1] = KERN_MALLOCSTATS;  
                 mib[2] = KERN_MALLOC_BUCKETS;  
                 siz = sizeof(buf);  
                 if (sysctl(mib, 3, buf, &siz, NULL, 0) < 0) {  
                         printf("Could not acquire information on kernel memory bucket sizes.\n");  
                         return;  
                 }  
   
                 bufp = buf;  
                 mib[2] = KERN_MALLOC_BUCKET;  
                 siz = sizeof(struct kmembuckets);  
                 i = 0;  
                 while ((ap = strsep(&bufp, ",")) != NULL) {  
                         mib[3] = atoi(ap);  
   
                         if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz,  
                                    NULL, 0) < 0) {  
                                 printf("Failed to read statistics for bucket %d.\n", mib[3]);  
                                 return;  
                         }  
                         i++;  
                 }  
         } else {  
                 kread(X_KMEMBUCKETS, buckets, sizeof(buckets));  
         }  
   
         for (first = 1, i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16;          for (first = 1, i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16;
              i++, kp++) {               i++, kp++) {
                 if (kp->kb_calls == 0)                  if (kp->kb_calls == 0)
Line 896 
Line 862 
                 if (first) {                  if (first) {
                         (void)printf("Memory statistics by bucket size\n");                          (void)printf("Memory statistics by bucket size\n");
                         (void)printf(                          (void)printf(
                 "    Size   In Use   Free           Requests  HighWater  Couldfree\n");                  "    Size   In Use   Free   Requests  HighWater  Couldfree\n");
                         first = 0;                          first = 0;
                 }                  }
                 size = 1 << i;                  size = 1 << i;
                 (void)printf("%8d %8qu %6qu %18qu %7qu %10qu\n", size,                  (void)printf("%8d %8ld %6ld %10ld %7ld %10ld\n", size,
                         kp->kb_total - kp->kb_totalfree,                          kp->kb_total - kp->kb_totalfree,
                         kp->kb_totalfree, kp->kb_calls,                          kp->kb_totalfree, kp->kb_calls,
                         kp->kb_highwat, kp->kb_couldfree);                          kp->kb_highwat, kp->kb_couldfree);
Line 976 
Line 942 
                 totreq += ks->ks_calls;                  totreq += ks->ks_calls;
         }          }
         (void)printf("\nMemory Totals:  In Use    Free    Requests\n");          (void)printf("\nMemory Totals:  In Use    Free    Requests\n");
         (void)printf("              %7luK %6luK    %8qu\n",          (void)printf("              %7ldK %6ldK    %8ld\n",
              (totuse + 1023) / 1024, (totfree + 1023) / 1024, totreq);               (totuse + 1023) / 1024, (totfree + 1023) / 1024, totreq);
 }  }
   
   void
   dopool(void)
   {
           int first, ovflw;
           long addr;
           long total = 0, inuse = 0;
           TAILQ_HEAD(,pool) pool_head;
           struct pool pool, *pp = &pool;
   
           kread(X_POOLHEAD, &pool_head, sizeof(pool_head));
           addr = (long)TAILQ_FIRST(&pool_head);
   
           for (first = 1; addr != 0; ) {
                   char name[32], maxp[32];
                   if (kvm_read(kd, addr, (void *)pp, sizeof *pp) != sizeof *pp) {
                           (void)fprintf(stderr,
                               "vmstat: pool chain trashed: %s\n",
                               kvm_geterr(kd));
                           exit(1);
                   }
                   if (kvm_read(kd, (long)pp->pr_wchan, name, sizeof name) < 0) {
                           (void)fprintf(stderr,
                               "vmstat: pool name trashed: %s\n",
                               kvm_geterr(kd));
                           exit(1);
                   }
                   name[31] = '\0';
   
                   if (first) {
                           (void)printf("Memory resource pool statistics\n");
                           (void)printf(
                               "%-11s%5s%9s%5s%9s%6s%6s%6s%6s%6s%6s%5s\n",
                               "Name",
                               "Size",
                               "Requests",
                               "Fail",
                               "Releases",
                               "Pgreq",
                               "Pgrel",
                               "Npage",
                               "Hiwat",
                               "Minpg",
                               "Maxpg",
                               "Idle");
                           first = 0;
                   }
                   if (pp->pr_maxpages == UINT_MAX)
                           sprintf(maxp, "inf");
                   else
                           sprintf(maxp, "%u", pp->pr_maxpages);
 /*  /*
    * Print single word.  `ovflow' is number of characters didn't fit
    * on the last word.  `fmt' is a format string to print this word.
    * It must contain asterisk for field width.  `width' is a width
    * occupied by this word.  `fixed' is a number of constant chars in
    * `fmt'.  `val' is a value to be printed using format string `fmt'.
    */
   #define PRWORD(ovflw, fmt, width, fixed, val) do {      \
           (ovflw) += printf((fmt),                        \
               (width) - (fixed) - (ovflw) > 0 ?           \
               (width) - (fixed) - (ovflw) : 0,            \
               (val)) - (width);                           \
           if ((ovflw) < 0)                                \
                   (ovflw) = 0;                            \
   } while (/* CONSTCOND */0)
                   ovflw = 0;
                   PRWORD(ovflw, "%-*s", 11, 0, name);
                   PRWORD(ovflw, " %*u", 5, 1, pp->pr_size);
                   PRWORD(ovflw, " %*lu", 9, 1, pp->pr_nget);
                   PRWORD(ovflw, " %*lu", 5, 1, pp->pr_nfail);
                   PRWORD(ovflw, " %*lu", 9, 1, pp->pr_nput);
                   PRWORD(ovflw, " %*lu", 6, 1, pp->pr_npagealloc);
                   PRWORD(ovflw, " %*lu", 6, 1, pp->pr_npagefree);
                   PRWORD(ovflw, " %*d", 6, 1, pp->pr_npages);
                   PRWORD(ovflw, " %*d", 6, 1, pp->pr_hiwat);
                   PRWORD(ovflw, " %*d", 6, 1, pp->pr_minpages);
                   PRWORD(ovflw, " %*s", 6, 1, maxp);
                   PRWORD(ovflw, " %*lu\n", 5, 1, pp->pr_nidle);
   
                   inuse += (pp->pr_nget - pp->pr_nput) * pp->pr_size;
                   total += pp->pr_npages * pp->pr_pagesz;
                   addr = (long)TAILQ_NEXT(pp, pr_poollist);
           }
   
           inuse /= 1024;
           total /= 1024;
           printf("\nIn use %ldK, total allocated %ldK; utilization %.1f%%\n",
               inuse, total, (double)(100 * inuse) / total);
   }
   
   /*
  * kread reads something from the kernel, given its nlist index.   * kread reads something from the kernel, given its nlist index.
  */   */
 void  void
Line 995 
Line 1051 
                 sym = namelist[nlx].n_name;                  sym = namelist[nlx].n_name;
                 if (*sym == '_')                  if (*sym == '_')
                         ++sym;                          ++sym;
                 errx(1, "symbol %s not defined", sym);                  (void)fprintf(stderr,
                       "vmstat: symbol %s not defined\n", sym);
                   exit(1);
         }          }
         if (kvm_read(kd, namelist[nlx].n_value, addr, size) != size) {          if (kvm_read(kd, namelist[nlx].n_value, addr, size) != size) {
                 sym = namelist[nlx].n_name;                  sym = namelist[nlx].n_name;
                 if (*sym == '_')                  if (*sym == '_')
                         ++sym;                          ++sym;
                 errx(1, "%s: %s", sym, kvm_geterr(kd));                  (void)fprintf(stderr, "vmstat: %s: %s\n", sym, kvm_geterr(kd));
                   exit(1);
         }          }
 }  }
   
 void  void
 usage()  usage()
 {  {
         (void)fprintf(stderr, "usage: %s [-fimst] [-c count] [-M core] "          (void)fprintf(stderr,
             "[-N system] [-w wait] [disks]\n", __progname);              "usage: vmstat [-fimst] [-c count] [-M core] \
   [-N system] [-w wait] [disks]\n");
         exit(1);          exit(1);
 }  }
   

Legend:
Removed from v.1.47  
changed lines
  Added in v.1.48