Hi Guys,

Doing a small disk benchmark in my laptop with dd, I found that dd and
iostats were reporting different numbers. To be precise, iostat was
returning half of the MB/sec than dd (24.5 vs 49 MB/sec).

Digging a bit on the iostat code, I realized that the "struct _disk" cpu
time was returning 200 timer ticks even though it was read every second. I
tested by booting my machine with bsd.sp (to use one core instead of two)
and now it was returning the right number.

It seems like the number of ticks are incrementing by a factor proportional
to the number of CPUs (I think this makes sense). This makes iostat to
report the wrong bandwidth disk utilization.

Here is a patch I implemented to fix the problem:

diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c
index 7da45b5..ffcd43a 100644
--- a/usr.sbin/iostat/iostat.c
+++ b/usr.sbin/iostat/iostat.c
@@ -64,6 +64,8 @@

 #include <sys/dkstat.h>
 #include <sys/time.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>

 #include <err.h>
 #include <ctype.h>
@@ -84,7 +86,7 @@ extern int    dk_ndrive;
 kvm_t *kd;
 char    *nlistf, *memf;

-int        hz, reps, interval;
+int        hz, reps, interval, ncpu;
 static int    todo = 0;

 volatile sig_atomic_t wantheader;
@@ -112,8 +114,9 @@ int dkinit(int);
 int
 main(int argc, char *argv[])
 {
-    int ch, hdrcnt;
+    int ch, hdrcnt, mib[2];
     struct timeval    tv;
+    size_t size;

     while ((ch = getopt(argc, argv, "Cc:dDIM:N:Tw:")) != -1)
         switch(ch) {
@@ -156,6 +159,11 @@ main(int argc, char *argv[])
     if (!ISSET(todo, SHOW_CPU | SHOW_TTY | SHOW_STATS_1 | SHOW_STATS_2))
         todo |= SHOW_CPU | SHOW_TTY | SHOW_STATS_1;

+    mib[0] = CTL_HW;
+    mib[1] = HW_NCPU;
+    size = sizeof(ncpu);
+    (void) sysctl(mib, 2, &ncpu, &size, NULL, 0);
+
     dkinit(0);
     dkreadstats();
     selectdrives(argv);
@@ -342,7 +350,7 @@ display(void)
     if (etime == 0.0)
         etime = 1.0;
     /* Convert to seconds. */
-    etime /= (float)hz;
+    etime /= (float)hz*ncpu;

     /* If we're showing totals only, then don't divide by the
      * system time.


Any thoughts?
Luis.

Reply via email to