Hi,

systat(1)'s vmstat view should not use statclock() ticks to count
elapsed time.  First, ticks are very low resolution and they aren't
always of equal length.  Second, we're counting the ticks from every
CPU on the system, so all the rates in the view are divided by the
number of CPUs.

Instead, compute an elapsed time with clock_gettime(2).  Prefer
CLOCK_UPTIME to CLOCK_MONOTONIC to exclude any time the system is
suspended.  With this change we can remove "stathz", "hertz", and the
secondary clock failure test.

For comparison, consider my laptop with 8 CPUs while it's building
clang.

Before:

   7 users Load 11.96 8.89 4.08                    jetsam.attlocal.net 18:05:37

            memory totals (in KB)            PAGING   SWAPPING     Interrupts
           real   virtual     free           in  out   in  out      234 total
Active  1352876   1352876 10132884   ops                                acpi0
All     5974204   5974204 43687312   pages                            1 inteldrm
                                                                      8 xhci0
Proc:r  d  s  w    Csw   Trp   Sys   Int   Sof  Flt       forks       3 iwm0
     9   157        27  2640  1320    13    35 2634       fkppw         nvme0
                                                          fksvm         azalia0
   0.1%Int   0.6%Spn   3.4%Sys  95.9%Usr   0.0%Idle       pwait         pckbc0
|    |    |    |    |    |    |    |    |    |    |       relck         pckbc0
==>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>        rlkok     200 clock
                                                          noram      22 ipi
Namei         Sys-cache    Proc-cache    No-cache     210 ndcpy
    Calls     hits    %    hits     %    miss   %         fltcp
    36633    35567   97                  1066   3    2466 zfod
                                                          cow
Disks   sd0   sd1                                  134225 fmin
seeks                                              178966 ftarg
xfers     2                                               itarg
speed   32K                                         11781 wired
  sec   0.0                                               pdfre
                                                          pdscn
                                                    -2549 pzidl       2 IPKTS
                                                       37 kmape         OPKTS

After:

   7 users Load 10.80 8.87 4.21                    jetsam.attlocal.net 18:06:04

            memory totals (in KB)            PAGING   SWAPPING     Interrupts
           real   virtual     free           in  out   in  out     1867 total
Active  1920708   1920708  9534016   ops                                acpi0
All     6573072   6573072 43088444   pages                           12 inteldrm
                                                                     62 xhci0
Proc:r  d  s  w    Csw   Trp   Sys   Int   Sof  Flt       forks      21 iwm0
     9   157       213 49039  6150   102   27349046       fkppw       7 nvme0
                                                          fksvm         azalia0
   0.0%Int   1.5%Spn   4.5%Sys  94.1%Usr   0.0%Idle       pwait         pckbc0
|    |    |    |    |    |    |    |    |    |    |     5 relck         pckbc0
@==>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>      5 rlkok    1600 clock
                                                          noram     165 ipi
Namei         Sys-cache    Proc-cache    No-cache    1966 ndcpy
    Calls     hits    %    hits     %    miss   %         fltcp
    26320    26198  100                   122   0   48171 zfod
                                                          cow
Disks   sd0   sd1                                  134225 fmin
seeks                                              178966 ftarg
xfers     7                                               itarg
speed  112K                                         12805 wired
  sec   0.0                                               pdfre
                                                          pdscn
                                                   -45812 pzidl       2 IPKTS
                                                       36 kmape         OPKTS

One standout difference is the "clock" interrupt rate.  It is off by a
factor of 8 in the first view and corrected in the second.

CC jmatthew@ and dlg@, who apparently spent some time trying to debug
the wrong problem because of this.

ok?

Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.76
diff -u -p -r1.76 main.c
--- main.c      12 Jul 2021 15:09:20 -0000      1.76
+++ main.c      21 Nov 2022 00:15:12 -0000
@@ -65,7 +65,7 @@ double        avenrun[3];
 double naptime = 5.0;
 int    verbose = 1;            /* to report kvm read errs */
 int    nflag = 1;
-int    ut, hz, stathz;
+int    ut, hz;
 char    hostname[HOST_NAME_MAX+1];
 WINDOW  *wnd;
 int    CMDLINE;
@@ -414,7 +414,6 @@ gethz(void)
        mib[1] = KERN_CLOCKRATE;
        if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1)
                return;
-       stathz = cinf.stathz;
        hz = cinf.hz;
 }
 
Index: systat.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.h,v
retrieving revision 1.24
diff -u -p -r1.24 systat.h
--- systat.h    18 Jan 2021 00:49:09 -0000      1.24
+++ systat.h    21 Nov 2022 00:15:12 -0000
@@ -58,7 +58,7 @@ extern kvm_t  *kd;
 extern long    ntext;
 extern int     *dk_select;
 extern int     dk_ndrive;
-extern int     hz, stathz;
+extern int     hz;
 extern double  naptime;
 extern size_t  nhosts;
 extern size_t  nports;
Index: vmstat.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/vmstat.c,v
retrieving revision 1.94
diff -u -p -r1.94 vmstat.c
--- vmstat.c    22 Feb 2022 17:35:01 -0000      1.94
+++ vmstat.c    21 Nov 2022 00:15:13 -0000
@@ -98,7 +98,6 @@ int select_vm(void);
 int vm_keyboard_callback(int);
 
 static time_t t;
-static float hertz;
 static int nintr;
 static long *intrloc;
 static char **intrname;
@@ -170,7 +169,6 @@ initvmstat(void)
        int mib[4], i;
        size_t size;
 
-       hertz = stathz;
        if (!dkinit(1))
                return(0);
 
@@ -323,7 +321,6 @@ labelkre(void)
                Y(fld); \
                putint((int)((float)s.fld/etime + 0.5), l, c, w); \
        } while (0)
-#define MAXFAIL 5
 
 static char cpuchar[] = { '|', '@', '=', '>', ' ' };
 static char cpuorder[] = { CP_INTR, CP_SPIN, CP_SYS, CP_USER, CP_IDLE };
@@ -331,33 +328,27 @@ static    char cpuorder[] = { CP_INTR, CP_S
 void
 showkre(void)
 {
+       static struct timespec prev;
+       struct timespec elapsed, now;
        float f1, f2;
        int psiz;
        u_int64_t inttotal, intcnt;
        int i, l, c;
-       static int failcnt = 0, first_run = 0;
+       static int first_run = 0;
        double etime;
 
+       clock_gettime(CLOCK_UPTIME, &now);
+       timespecsub(&now, &prev, &elapsed);
+       prev = now;
        if (state == TIME) {
                if (!first_run) {
                        first_run = 1;
                        return;
                }
        }
-       etime = 0;
-       for (i = 0; i < CPUSTATES; i++) {
+       etime = elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0;
+       for (i = 0; i < CPUSTATES; i++)
                X(cpustats.cs_time);
-               etime += s.cpustats.cs_time[i];
-       }
-       if (etime < 5.0) {      /* < 5 ticks - ignore this trash */
-               if (failcnt++ >= MAXFAIL) {
-                       error("The alternate system clock has died!");
-                       failcnt = 0;
-               }
-               return;
-       }
-       failcnt = 0;
-       etime /= hertz;
        inttotal = 0;
        for (i = 0; i < nintr; i++) {
                t = intcnt = s.intrcnt[i];

Reply via email to