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.