CPU report in first line of "vmstat 1" is meaningless

From: Ed Maste <emaste_at_freebsd.org>
Date: Mon, 18 Oct 2010 13:43:31 -0400
The us/sy/id CPU usage numbers in the first line of vmstat are not useful,
because they're calculated based on kern.cp_times since boot, and not a
delta as are all subsequent lines.  If the system has been up long enough
wrapping may come in to play, giving negative results.  For example, on
one machine I see:

$ vmstat 1
 procs     memory     page                disks     faults         cpu
 r b w    avm   fre   flt  re pi po   fr sr da0 pa0   in   sy   cs us sy id
 1 0 2  1097M  227M   101   0  0  0  195 45   0   0  483   40  243 -24 -33 157
 1 0 2  1102M  222M  1396   0  0  0    0  0   0   0  159 2170  826 25  2 74
 1 0 2  1107M  218M  1124   0  0  0    0  0   0   0  146 2217  789 24  2 74


Should we wait for one interval before displaying the first line, or
display nothing (or a placeholder like '-')?

Below is a quick patch that illustrates the issue, and implements the
"display nothing" option.  With the patch the output looks like:

$ vmstat 1
 procs      memory      page                   disk   faults         cpu
 r b w     avm    fre   flt  re  pi  po    fr  sr ad0   in   sy   cs us sy id
 3 0 0   1971M    85M   326   0   0   0   334   5   0  457 3674 1495
 2 0 0   1971M    85M    23   0   0   0     0   0   0  301 3634 1209  5  7 88
 1 0 0   1971M    85M    74   0   0   0     0   0   0  510 4655 1619  7  3 90

And the patch:

Index: usr.bin/vmstat/vmstat.c
===================================================================
--- usr.bin/vmstat/vmstat.c     (revision 214019)
+++ usr.bin/vmstat/vmstat.c     (working copy)
_at__at_ -658,6 +658,7 _at__at_
        int ncpus, maxid;
        u_long cpumask;
        int rate_adj;
+       int have_prev_cp_times = 0;

        uptime = getuptime();
        halfuptime = uptime / 2;
_at__at_ -803,10 +804,13 _at__at_
                    (unsigned long)rate(sum.v_intr - osum.v_intr),
                    (unsigned long)rate(sum.v_syscall - osum.v_syscall),
                    (unsigned long)rate(sum.v_swtch - osum.v_swtch));
-               if (Pflag)
-                       pcpustats(ncpus, cpumask, maxid);
-               else
-                       cpustats();
+               if (have_prev_cp_times) {
+                       if (Pflag)
+                               pcpustats(ncpus, cpumask, maxid);
+                       else
+                               cpustats();
+               } else
+                       have_prev_cp_times = 1;
                (void)printf("\n");
                (void)fflush(stdout);
                if (reps >= 0 && --reps <= 0)

-Ed
Received on Mon Oct 18 2010 - 15:54:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:08 UTC