Index | Thread | Search

From:
Scott Cheloha <scottcheloha@gmail.com>
Subject:
systat(1): iostat: compute rates with elapsed time
To:
tech@openbsd.org
Date:
Thu, 4 Apr 2024 14:18:54 -0500

Download raw body.

Thread
In TIME mode, the iostat view sets etime to naptime before computing
rates.  This is wrong.  The elapsed time is never exactly naptime.

Instead, measure the real elapsed time between each print_io() call.
We need to read the clock during every call, regardless of mode,
because the mode can change between updates.

This patch also changes the iostat view's behavior during the first
update.  During that first update, iostat has no prior data to use
when computing rates.  Currently, the resulting output is "totals
since boot divided by naptime".  Here's a concrete example:

$ systat -d1 io 1
DEVICE          READ    WRITE     RTPS    WTPS     SEC
sd0         4544872K 7316640K   365102  687727   101.9
sd1                0        0        0       0     0.0
Totals      4544872K 7316640K   365102  687727   101.9
$ systat -d1 io 2
DEVICE          READ    WRITE     RTPS    WTPS     SEC
sd0         2272436K 3658335K   182551  343866    50.9
sd1                0        0        0       0     0.0
Totals      2272436K 3658335K   182551  343866    50.9
$ systat -d io 0.5
DEVICE          READ    WRITE     RTPS    WTPS     SEC
sd0         9089744K   14295M   730204 1376152   204.7
sd1                0        0        0       0     0.0
Totals      9089744K   14295M   730204 1376152   204.7

The second output is half the first (1 / 2).  The third output is
twice the first (1 / 0.5).  This is difficult to explain, let alone
document.  The numbers are also meaningless.

IMHO, if we're going to print something during that first update, it
makes more sense to unconditionally set etime to 1.0 and print the
totals.

Thoughts?  ok?

Index: iostat.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/iostat.c,v
diff -u -p -r1.50 iostat.c
--- iostat.c	14 Aug 2021 14:22:26 -0000	1.50
+++ iostat.c	4 Apr 2024 19:15:29 -0000
@@ -166,13 +166,23 @@ read_io(void)
 void
 print_io(void)
 {
+	static struct timespec prev;
+	struct timespec elapsed, now;
+	static int first = 1;
 	int n, count = 0;
 	int curr;
 
-	if (state == BOOT)
+	clock_gettime(CLOCK_MONOTONIC, &now);
+	if (first) {
+		first = 0;
 		etime = 1.0;
-	else
-		etime = naptime;
+	} else if (state == BOOT) {
+		etime = 1.0;
+	} else {
+		timespecsub(&now, &prev, &elapsed);
+		etime = elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0;
+	}
+	prev = now;
 
 	/* XXX engine internals: save and restore curr_line for bcache */
 	curr = curr_line;