kernel - Fix vmtotal sysctl
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Oct 2010 23:07:32 +0000 (16:07 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Oct 2010 23:41:48 +0000 (16:41 -0700)
* Recognize unbounded VM objects and do not try to include their sizes
  in the vmtotal structure.

* Should fix systat -vm output for the All/Tot entry.

* Redo the vmstat structure.  Use long's and int64_t's as
  appropriate.

* Adjust systat and vmstat to deal with the new field widths
  in struct vmstat.

Reported-by: Antonio Huete Jimenez <ahuete.devel@gmail.com>
sys/sys/vmmeter.h
sys/vm/vm_meter.c
usr.bin/systat/vmstat.c
usr.bin/vmstat/vmstat.c

index 48baf2e..006810f 100644 (file)
@@ -135,20 +135,20 @@ extern struct vmstats vmstats;
 /* systemwide totals computed every five seconds */
 struct vmtotal
 {
-       int16_t t_rq;           /* length of the run queue */
-       int16_t t_dw;           /* jobs in ``disk wait'' (neg priority) */
-       int16_t t_pw;           /* jobs in page wait */
-       int16_t t_sl;           /* jobs sleeping in core */
-       int16_t t_sw;           /* swapped out runnable/short block jobs */
-       int32_t t_vm;           /* total virtual memory */
-       int32_t t_avm;          /* active virtual memory */
-       int32_t t_rm;           /* total real memory in use */
-       int32_t t_arm;          /* active real memory */
-       int32_t t_vmshr;        /* shared virtual memory */
-       int32_t t_avmshr;       /* active shared virtual memory */
-       int32_t t_rmshr;        /* shared real memory */
-       int32_t t_armshr;       /* active shared real memory */
-       int32_t t_free;         /* free memory pages */
+       long    t_rq;           /* length of the run queue */
+       long    t_dw;           /* jobs in ``disk wait'' (neg priority) */
+       long    t_pw;           /* jobs in page wait */
+       long    t_sl;           /* jobs sleeping in core */
+       long    t_sw;           /* swapped out runnable/short block jobs */
+       int64_t t_vm;           /* total virtual memory */
+       int64_t t_avm;          /* active virtual memory */
+       long    t_rm;           /* total real memory in use */
+       long    t_arm;          /* active real memory */
+       int64_t t_vmshr;        /* shared virtual memory */
+       int64_t t_avmshr;       /* active shared virtual memory */
+       long    t_rmshr;        /* shared real memory */
+       long    t_armshr;       /* active shared real memory */
+       long    t_free;         /* free memory pages */
 };
 
 #ifdef PGINPROF
index 657a32a..6acc877 100644 (file)
@@ -126,7 +126,19 @@ do_vmtotal(SYSCTL_HANDLER_ARGS)
                        continue;
                if (object->type == OBJT_DEVICE)
                        continue;
-               totalp->t_vm += object->size;
+               if (object->size >= 0x7FFFFFFF) {
+                       /*
+                        * Probably unbounded anonymous memory (really
+                        * bounded by related vm_map_entry structures which
+                        * we do not have access to in this loop).
+                        */
+                       totalp->t_vm += object->resident_page_count;
+               } else {
+                       /*
+                        * It's questionable how useful this is but...
+                        */
+                       totalp->t_vm += object->size;
+               }
                totalp->t_rm += object->resident_page_count;
                if (object->flags & OBJ_ACTIVE) {
                        totalp->t_avm += object->size;
index 6b9998e..87e1e5a 100644 (file)
@@ -102,7 +102,7 @@ static void allocinfo(struct Info *);
 static void copyinfo(struct Info *, struct Info *);
 static void dinfo(int, int, struct statinfo *, struct statinfo *);
 static void getinfo(struct Info *);
-static void putint(int, int, int, int, int);
+static void putlong(long, int, int, int, int);
 static void putfloat(double, int, int, int, int, int);
 static void putlongdouble(long double, int, int, int, int, int);
 static void putlongdoublez(long double, int, int, int, int, int);
@@ -383,7 +383,7 @@ labelkre(void)
        if(state == TIME) s1.nchstats.fld = t;}
 #define PUTRATE(fld, l, c, w) \
        Y(fld); \
-       putint((int)((float)s.fld/etime + 0.5), l, c, w, 'D')
+       putlong((long)((float)s.fld/etime + 0.5), l, c, w, 'D')
 #define MAXFAIL 5
 
 #define CPUSTATES 5
@@ -401,8 +401,10 @@ void
 showkre(void)
 {
        float f1, f2;
-       int psiz, inttotal;
-       int i, l, lc;
+       int psiz;
+       int i, lc;
+       long inttotal;
+       long l;
        static int failcnt = 0;
        double total_time;
 
@@ -447,11 +449,11 @@ showkre(void)
                                intrname[i]);
                }
                X(intrcnt);
-               l = (int)((float)s.intrcnt[i]/etime + 0.5);
+               l = (long)((float)s.intrcnt[i]/etime + 0.5);
                inttotal += l;
-               putint(l, intrloc[i], INTSCOL + 2, 6, 'D');
+               putlong(l, intrloc[i], INTSCOL + 2, 6, 'D');
        }
-       putint(inttotal, INTSROW + 1, INTSCOL + 2, 6, 'D');
+       putlong(inttotal, INTSROW + 1, INTSCOL + 2, 6, 'D');
        Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss);
        Z(ncs_longhits); Z(ncs_longmiss); Z(ncs_neghits);
        s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits +
@@ -479,36 +481,36 @@ showkre(void)
                        addch(cpuchar[lc]);
        }
 
-       putint(ucount(), STATROW, STATCOL, 3, 'D');
+       putlong(ucount(), STATROW, STATCOL, 3, 'D');
        putfloat(avenrun[0], STATROW, STATCOL + 18, 6, 2, 0);
        putfloat(avenrun[1], STATROW, STATCOL + 25, 6, 2, 0);
        putfloat(avenrun[2], STATROW, STATCOL + 32, 6, 2, 0);
        mvaddstr(STATROW, STATCOL + 53, buf);
-#define pgtokb(pg)     (int)((intmax_t)(pg) * vms.v_page_size / 1024)
-#define pgtomb(pg)     (int)((intmax_t)(pg) * vms.v_page_size / (1024 * 1024))
-       putint(pgtomb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8, 'M');
-       putint(pgtomb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8, 'M');
-       putint(pgtomb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9, 'M');
-       putint(pgtomb(total.t_avmshr), MEMROW + 2, MEMCOL + 28, 9, 'M');
-       putint(pgtomb(total.t_rm), MEMROW + 3, MEMCOL + 3, 8, 'M');
-       putint(pgtomb(total.t_rmshr), MEMROW + 3, MEMCOL + 11, 8, 'M');
-       putint(pgtomb(total.t_vm), MEMROW + 3, MEMCOL + 19, 9, 'M');
-       putint(pgtomb(total.t_vmshr), MEMROW + 3, MEMCOL + 28, 9, 'M');
-       putint(pgtomb(total.t_free), MEMROW + 2, MEMCOL + 37, 8, 'M');
-       putint(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 0, 3, 'D');
-       putint(total.t_pw, PROCSROW + 1, PROCSCOL + 3, 3, 'D');
-       putint(total.t_dw, PROCSROW + 1, PROCSCOL + 6, 3, 'D');
-       putint(total.t_sl, PROCSROW + 1, PROCSCOL + 9, 3, 'D');
-       putint(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3, 'D');
+#define pgtokb(pg)     (long)((intmax_t)(pg) * vms.v_page_size / 1024)
+#define pgtomb(pg)     (long)((intmax_t)(pg) * vms.v_page_size / (1024 * 1024))
+       putlong(pgtomb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8, 'M');
+       putlong(pgtomb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8, 'M');
+       putlong(pgtomb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9, 'M');
+       putlong(pgtomb(total.t_avmshr), MEMROW + 2, MEMCOL + 28, 9, 'M');
+       putlong(pgtomb(total.t_rm), MEMROW + 3, MEMCOL + 3, 8, 'M');
+       putlong(pgtomb(total.t_rmshr), MEMROW + 3, MEMCOL + 11, 8, 'M');
+       putlong(pgtomb(total.t_vm), MEMROW + 3, MEMCOL + 19, 9, 'M');
+       putlong(pgtomb(total.t_vmshr), MEMROW + 3, MEMCOL + 28, 9, 'M');
+       putlong(pgtomb(total.t_free), MEMROW + 2, MEMCOL + 37, 8, 'M');
+       putlong(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 0, 3, 'D');
+       putlong(total.t_pw, PROCSROW + 1, PROCSCOL + 3, 3, 'D');
+       putlong(total.t_dw, PROCSROW + 1, PROCSCOL + 6, 3, 'D');
+       putlong(total.t_sl, PROCSROW + 1, PROCSCOL + 9, 3, 'D');
+       putlong(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3, 'D');
        if (extended_vm_stats == 0) {
                PUTRATE(Vmm.v_zfod, VMSTATROW + 0, VMSTATCOL + 4, 5);
        }
        PUTRATE(Vmm.v_cow_faults, VMSTATROW + 1, VMSTATCOL + 3, 6);
-       putint(pgtokb(vms.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_active_count), VMSTATROW + 3, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_free_count), VMSTATROW + 6, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_active_count), VMSTATROW + 3, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_free_count), VMSTATROW + 6, VMSTATCOL, 9, 'K');
        PUTRATE(Vmm.v_dfree, VMSTATROW + 7, VMSTATCOL, 9);
        PUTRATE(Vmm.v_pfree, VMSTATROW + 8, VMSTATCOL, 9);
        PUTRATE(Vmm.v_reactivated, VMSTATROW + 9, VMSTATCOL, 9);
@@ -520,17 +522,17 @@ showkre(void)
                PUTRATE(Vmm.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9);
                PUTRATE(Vmm.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9);
 #define nz(x)  ((x) ? (x) : 1)
-               putint((s.Vmm.v_zfod - s.Vmm.v_ozfod) * 100 / nz(s.Vmm.v_zfod),
+               putlong((s.Vmm.v_zfod - s.Vmm.v_ozfod) * 100 / nz(s.Vmm.v_zfod),
                    VMSTATROW + 13, VMSTATCOL - 16, 9, 'D');
 #undef nz
                PUTRATE(Vmm.v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9);
        }
 
-       putint(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9, 'K');
-       putint(s.dirtybufspace/1024, VMSTATROW + 14, VMSTATCOL, 9, 'K');
-       putint(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9, 'D');
-       putint(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9, 'D');
-       putint(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9, 'D');
+       putlong(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9, 'K');
+       putlong(s.dirtybufspace/1024, VMSTATROW + 14, VMSTATCOL, 9, 'K');
+       putlong(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9, 'D');
+       putlong(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9, 'D');
+       putlong(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9, 'D');
        PUTRATE(Vmm.v_vnodein, PAGEROW + 2, PAGECOL + 5, 5);
        PUTRATE(Vmm.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5);
        PUTRATE(Vmm.v_swapin, PAGEROW + 2, PAGECOL + 17, 5);
@@ -566,9 +568,9 @@ showkre(void)
                        }
                }
 #define nz(x)  ((x) ? (x) : 1)
-       putint(s.nchpathcount, NAMEIROW + 1, NAMEICOL + 3, 9, 'D');
+       putlong(s.nchpathcount, NAMEIROW + 1, NAMEICOL + 3, 9, 'D');
 
-       putint(nchtotal.ncs_longhits, NAMEIROW + 1, NAMEICOL + 12, 7, 'D');
+       putlong(nchtotal.ncs_longhits, NAMEIROW + 1, NAMEICOL + 12, 7, 'D');
        putfloat(nchtotal.ncs_longhits * 100.0 / nz(s.nchpathcount),
            NAMEIROW + 1, NAMEICOL + 19, 4, 0, 0);
 
@@ -657,7 +659,7 @@ ucount(void)
 }
 
 static void
-putint(int n, int l, int lc, int w, int type)
+putlong(long n, int l, int lc, int w, int type)
 {
        char b[128];
        int xtype;
@@ -668,7 +670,7 @@ putint(int n, int l, int lc, int w, int type)
                        addch(' ');
                return;
        }
-       snprintf(b, sizeof(b), "%*d", w, n);
+       snprintf(b, sizeof(b), "%*ld", w, n);
        if (strlen(b) > (size_t)w) {
                if (type == 'D') {
                        n /= 1000;
@@ -677,7 +679,7 @@ putint(int n, int l, int lc, int w, int type)
                        n /= 1024;
                        xtype = 'M';
                }
-               snprintf(b, sizeof(b), "%*d%c", w - 1, n, xtype);
+               snprintf(b, sizeof(b), "%*ld%c", w - 1, n, xtype);
                if (strlen(b) > (size_t)w) {
                        if (type == 'D') {
                                n /= 1000;
@@ -686,7 +688,7 @@ putint(int n, int l, int lc, int w, int type)
                                n /= 1024;
                                xtype = 'G';
                        }
-                       snprintf(b, sizeof(b), "%*d%c", w - 1, n, xtype);
+                       snprintf(b, sizeof(b), "%*ld%c", w - 1, n, xtype);
                        if (strlen(b) > (size_t)w) {
                                while (w-- > 0)
                                        addch('*');
index 15cc538..3a6e1e4 100644 (file)
@@ -457,31 +457,37 @@ dovmstat(u_int interval, int reps)
                        perror("sysctlbyname: vm.vmtotal");
                        exit(1);
                } 
-               printf("%2d %1d %1d",
+               printf("%2ld %1ld %1ld",
                    total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw);
-#define vmstat_pgtok(a) ((a) * vms.v_page_size >> 10)
-#define rate(x)        (initial ? (x) : ((x) * 1000 + interval / 2) / interval)
-               printf(" %7ld %6ld ",
-                   (long)vmstat_pgtok(total.t_avm), (long)vmstat_pgtok(total.t_free));
-               printf("%4lu ",
-                   (u_long)rate(vmm.v_vm_faults - ovmm.v_vm_faults));
-               printf("%3lu ",
-                   (u_long)rate(vmm.v_reactivated - ovmm.v_reactivated));
-               printf("%3lu ",
-                   (u_long)rate(vmm.v_swapin + vmm.v_vnodein -
-                   (ovmm.v_swapin + ovmm.v_vnodein)));
-               printf("%3lu ",
-                   (u_long)rate(vmm.v_swapout + vmm.v_vnodeout -
-                   (ovmm.v_swapout + ovmm.v_vnodeout)));
-               printf("%3lu ",
-                   (u_long)rate(vmm.v_tfree - ovmm.v_tfree));
-               printf("%3lu ",
-                   (u_long)rate(vmm.v_pdpages - ovmm.v_pdpages));
+
+#define vmstat_pgtok(a)        \
+       (intmax_t)(((intmax_t)(a) * vms.v_page_size) >> 10)
+#define rate(x)                \
+       (intmax_t)(initial ? (x) : ((intmax_t)(x) * 1000 + interval / 2) \
+                                  / interval)
+
+               printf(" %7jd %6jd ",
+                      vmstat_pgtok(total.t_avm),
+                      vmstat_pgtok(total.t_free));
+               printf("%4ju ",
+                      rate(vmm.v_vm_faults - ovmm.v_vm_faults));
+               printf("%3ju ",
+                      rate(vmm.v_reactivated - ovmm.v_reactivated));
+               printf("%3ju ",
+                      rate(vmm.v_swapin + vmm.v_vnodein -
+                           (ovmm.v_swapin + ovmm.v_vnodein)));
+               printf("%3ju ",
+                      rate(vmm.v_swapout + vmm.v_vnodeout -
+                           (ovmm.v_swapout + ovmm.v_vnodeout)));
+               printf("%3ju ",
+                      rate(vmm.v_tfree - ovmm.v_tfree));
+               printf("%3ju ",
+                      rate(vmm.v_pdpages - ovmm.v_pdpages));
                devstats();
-               printf("%4lu %4lu %3lu ",
-                   (u_long)rate(vmm.v_intr - ovmm.v_intr),
-                   (u_long)rate(vmm.v_syscall - ovmm.v_syscall),
-                   (u_long)rate(vmm.v_swtch - ovmm.v_swtch));
+               printf("%4ju %4ju %3ju ",
+                      rate(vmm.v_intr - ovmm.v_intr),
+                      rate(vmm.v_syscall - ovmm.v_syscall),
+                      rate(vmm.v_swtch - ovmm.v_swtch));
                cpustats();
                printf("\n");
                fflush(stdout);