From 3442cec3872d6c07eda21d147ebdd35ef2fea620 Mon Sep 17 00:00:00 2001
From: Sebastien GODARD <sysstat@users.noreply.github.com>
Date: Sat, 27 May 2023 16:31:05 +0200
Subject: [PATCH] iostat: Try to avoid some more negative values (#355)

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>

Reference:https://github.com/sysstat/sysstat/commit/3442cec3872d6c07eda21d147ebdd35ef2fea620
Conflict:NA

---
 iostat.c   | 42 ++++++++++++++++++++++++++++++------------
 rd_stats.c |  4 ++--
 2 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/iostat.c b/iostat.c
index bd21eb4..9787e09 100644
--- a/iostat.c
+++ b/iostat.c
@@ -1158,6 +1158,8 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 		/* tps */
 		/* Origin (unmerged) flush operations are counted as writes */
 		cprintf_f(NO_UNIT, 1, 8, 2,
+			  ioi->rd_ios + ioi->wr_ios + ioi->dc_ios < ioj->rd_ios + ioj->wr_ios + ioj->dc_ios ?
+			  0.0 :
 			  S_VALUE(ioj->rd_ios + ioj->wr_ios + ioj->dc_ios,
 				  ioi->rd_ios + ioi->wr_ios + ioi->dc_ios, itv));
 		/* kB/s */
@@ -1168,6 +1170,8 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 			  xios->sectors);
 		/* rqm/s */
 		cprintf_f(NO_UNIT, 1, 8, 2,
+			  ioi->rd_merges + ioi->wr_merges + ioi->dc_merges < ioj->rd_merges + ioj->wr_merges + ioj->dc_merges ?
+			  0.0 :
 			  S_VALUE(ioj->rd_merges + ioj->wr_merges + ioj->dc_merges,
 				  ioi->rd_merges + ioi->wr_merges + ioi->dc_merges, itv));
 		/* await */
@@ -1178,6 +1182,7 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 			  xds->arqsz / 2);
 		/* aqu-sz */
 		cprintf_f(NO_UNIT, 1, 7, 2,
+			  ioi->rq_ticks < ioj->rq_ticks ? 0.0 :
 			  S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
 		/*
 		 * %util
@@ -1199,6 +1204,7 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 				  xios->rsectors);
 			/* rrqm/s */
 			cprintf_f(NO_UNIT, 1, 8, 2,
+				  ioi->rd_merges < ioj->rd_merges ? 0.0 :
 				  S_VALUE(ioj->rd_merges, ioi->rd_merges, itv));
 			/* %rrqm */
 			cprintf_pc(DISPLAY_UNIT(flags), 1, 6, 2,
@@ -1223,6 +1229,7 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 				  xios->wsectors);
 			/* wrqm/s */
 			cprintf_f(NO_UNIT, 1, 8, 2,
+				  ioi->wr_merges < ioj->wr_merges ? 0.0 :
 				  S_VALUE(ioj->wr_merges, ioi->wr_merges, itv));
 			/* %wrqm */
 			cprintf_pc(DISPLAY_UNIT(flags), 1, 6, 2,
@@ -1247,6 +1254,7 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 				  xios->dsectors);
 			/* drqm/s */
 			cprintf_f(NO_UNIT, 1, 8, 2,
+				  ioi->dc_merges < ioj->dc_merges ? 0.0 :
 				  S_VALUE(ioj->dc_merges, ioi->dc_merges, itv));
 			/* %drqm */
 			cprintf_pc(DISPLAY_UNIT(flags), 1, 6, 2,
@@ -1268,6 +1276,7 @@ void write_plain_ext_stat(unsigned long long itv, int fctr, int hpart,
 				  xios->f_await);
 			/* aqu-sz */
 			cprintf_f(NO_UNIT, 1, 7, 2,
+				  ioi->rq_ticks < ioj->rq_ticks ? 0.0 :
 				  S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
 			/*
 			 * %util
@@ -1325,6 +1334,8 @@ void write_json_ext_stat(int tab, unsigned long long itv, int fctr,
 	if (DISPLAY_SHORT_OUTPUT(flags)) {
 		printf("\"tps\": %.2f, \"",
 		       /* Origin (unmerged) flush operations are counted as writes */
+		       ioi->rd_ios + ioi->wr_ios + ioi->dc_ios < ioj->rd_ios + ioj->wr_ios + ioj->dc_ios ?
+		       0.0 :
 		       S_VALUE(ioj->rd_ios + ioj->wr_ios + ioj->dc_ios,
 			       ioi->rd_ios + ioi->wr_ios + ioi->dc_ios, itv));
 		if (DISPLAY_MEGABYTES(flags)) {
@@ -1339,11 +1350,14 @@ void write_json_ext_stat(int tab, unsigned long long itv, int fctr,
 		printf("\": %.2f, \"rqm/s\": %.2f, \"await\": %.2f, "
 		       "\"areq-sz\": %.2f, \"aqu-sz\": %.2f, ",
 		       xios->sectors /= fctr,
+		       ioi->rd_merges + ioi->wr_merges + ioi->dc_merges < ioj->rd_merges + ioj->wr_merges + ioj->dc_merges ?
+		       0.0 :
 		       S_VALUE(ioj->rd_merges + ioj->wr_merges + ioj->dc_merges,
 			       ioi->rd_merges + ioi->wr_merges + ioi->dc_merges, itv),
 		       xds->await,
 		       xds->arqsz / 2,
-		       S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
+		       ioi->rq_ticks < ioj->rq_ticks ? 0.0
+						     : S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
 	}
 	else {
 		printf("\"r/s\": %.2f, \"w/s\": %.2f, \"d/s\": %.2f, \"f/s\": %.2f, ",
@@ -1373,9 +1387,12 @@ void write_json_ext_stat(int tab, unsigned long long itv, int fctr,
 		       "\"r_await\": %.2f, \"w_await\": %.2f, \"d_await\": %.2f, \"f_await\": %.2f, "
 		       "\"rareq-sz\": %.2f, \"wareq-sz\": %.2f, \"dareq-sz\": %.2f, "
 		       "\"aqu-sz\": %.2f, ",
-		       S_VALUE(ioj->rd_merges, ioi->rd_merges, itv),
-		       S_VALUE(ioj->wr_merges, ioi->wr_merges, itv),
-		       S_VALUE(ioj->dc_merges, ioi->dc_merges, itv),
+		       ioi->rd_merges < ioj->rd_merges ? 0.0
+						       : S_VALUE(ioj->rd_merges, ioi->rd_merges, itv),
+		       ioi->wr_merges < ioj->wr_merges ? 0.0
+						       : S_VALUE(ioj->wr_merges, ioi->wr_merges, itv),
+		       ioi->dc_merges < ioj->dc_merges ? 0.0
+						       : S_VALUE(ioj->dc_merges, ioi->dc_merges, itv),
 		       xios->rrqm_pc,
 		       xios->wrqm_pc,
 		       xios->drqm_pc,
@@ -1386,7 +1403,8 @@ void write_json_ext_stat(int tab, unsigned long long itv, int fctr,
 		       xios->rarqsz / 2,
 		       xios->warqsz / 2,
 		       xios->darqsz / 2,
-		       S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
+		       ioi->rq_ticks < ioj->rq_ticks ? 0.0
+						     : S_VALUE(ioj->rq_ticks, ioi->rq_ticks, itv) / 1000.0);
 	}
 
 	if (d->dev_tp > T_GROUP) {
@@ -1486,11 +1504,11 @@ void write_ext_stat(unsigned long long itv, int fctr, int hpart,
 				       ((ioi->rd_merges - ioj->rd_merges) + (ioi->rd_ios - ioj->rd_ios)) * 100 :
 				       0.0;
 			/* r_await */
-			xios.r_await = (ioi->rd_ios - ioj->rd_ios) ?
+			xios.r_await = (ioi->rd_ios > ioj->rd_ios) ?
 				       (ioi->rd_ticks - ioj->rd_ticks) /
 				       ((double) (ioi->rd_ios - ioj->rd_ios)) : 0.0;
 			/* rareq-sz (still in sectors, not kB) */
-			xios.rarqsz = (ioi->rd_ios - ioj->rd_ios) ?
+			xios.rarqsz = (ioi->rd_ios > ioj->rd_ios) ?
 				      (ioi->rd_sectors - ioj->rd_sectors) / ((double) (ioi->rd_ios - ioj->rd_ios)) :
 				      0.0;
 		}
@@ -1501,11 +1519,11 @@ void write_ext_stat(unsigned long long itv, int fctr, int hpart,
 				       ((ioi->wr_merges - ioj->wr_merges) + (ioi->wr_ios - ioj->wr_ios)) * 100 :
 				       0.0;
 			/* w_await */
-			xios.w_await = (ioi->wr_ios - ioj->wr_ios) ?
+			xios.w_await = (ioi->wr_ios > ioj->wr_ios) ?
 				       (ioi->wr_ticks - ioj->wr_ticks) /
 				       ((double) (ioi->wr_ios - ioj->wr_ios)) : 0.0;
 			/* wareq-sz (still in sectors, not kB) */
-			xios.warqsz = (ioi->wr_ios - ioj->wr_ios) ?
+			xios.warqsz = (ioi->wr_ios > ioj->wr_ios) ?
 				      (ioi->wr_sectors - ioj->wr_sectors) / ((double) (ioi->wr_ios - ioj->wr_ios)) :
 				      0.0;
 		}
@@ -1516,17 +1534,17 @@ void write_ext_stat(unsigned long long itv, int fctr, int hpart,
 				       ((ioi->dc_merges - ioj->dc_merges) + (ioi->dc_ios - ioj->dc_ios)) * 100 :
 				       0.0;
 			/* d_await */
-			xios.d_await = (ioi->dc_ios - ioj->dc_ios) ?
+			xios.d_await = (ioi->dc_ios > ioj->dc_ios) ?
 				       (ioi->dc_ticks - ioj->dc_ticks) /
 				       ((double) (ioi->dc_ios - ioj->dc_ios)) : 0.0;
 			/* dareq-sz (still in sectors, not kB) */
-			xios.darqsz = (ioi->dc_ios - ioj->dc_ios) ?
+			xios.darqsz = (ioi->dc_ios > ioj->dc_ios) ?
 				      (ioi->dc_sectors - ioj->dc_sectors) / ((double) (ioi->dc_ios - ioj->dc_ios)) :
 				      0.0;
 		}
 		if ((hpart == 4) || !hpart) {
 			/* f_await */
-			xios.f_await = (ioi->fl_ios - ioj->fl_ios) ?
+			xios.f_await = (ioi->fl_ios > ioj->fl_ios) ?
 				       (ioi->fl_ticks - ioj->fl_ticks) /
 				       ((double) (ioi->fl_ios - ioj->fl_ios)) : 0.0;
 		}
diff --git a/rd_stats.c b/rd_stats.c
index 9c91dac..3905ac3 100644
--- a/rd_stats.c
+++ b/rd_stats.c
@@ -385,10 +385,10 @@ void compute_ext_disk_stats(struct stats_disk *sdc, struct stats_disk *sdp,
 	 * => no need for further scaling.
 	 * Origin (unmerged) flush operations are counted as writes.
 	 */
-	xds->await = (sdc->nr_ios - sdp->nr_ios) ?
+	xds->await = (sdc->nr_ios > sdp->nr_ios) ?
 		((sdc->rd_ticks - sdp->rd_ticks) + (sdc->wr_ticks - sdp->wr_ticks) + (sdc->dc_ticks - sdp->dc_ticks)) /
 		((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
-	xds->arqsz = (sdc->nr_ios - sdp->nr_ios) ?
+	xds->arqsz = (sdc->nr_ios > sdp->nr_ios) ?
 		((sdc->rd_sect - sdp->rd_sect) + (sdc->wr_sect - sdp->wr_sect) + (sdc->dc_sect - sdp->dc_sect)) /
 		((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
 }
-- 
2.33.0
