[PATCH v2 3/4] blkparse: Initialize and test for undefined request tracking timestamps

Andreas Gruenbacher <[email protected]>
Newsgroups org.kernel.vger.linux-btrace
Message-ID <[email protected]>
Currently, event tracking timestamps aren't initialized at all even though some
places in the code assume that a value of 0 indicates 'undefined'.  However, 0
is the timestamp of the first event, so use -1ULL for 'undefined' instead.

In addition, make sure timestamps are only initialized once, and always check
if timestamps are defined before using them.

Signed-off-by: Andreas Gruenbacher <[email protected]>
---
 blkparse.c | 46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/blkparse.c b/blkparse.c
index c31a5c2..fcc0ccd 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <getopt.h>
 #include <errno.h>
@@ -326,6 +327,21 @@ static int have_drv_data = 0;
 #define CPU_IDX(cpu)	((cpu) / CPUS_PER_LONG)
 #define CPU_BIT(cpu)	((cpu) & (CPUS_PER_LONG - 1))
 
+static void io_warn_unless(struct blk_io_trace *t, int condition,
+			   const char *fmt, ...)
+{
+	va_list ap;
+
+	if (condition)
+		return;
+	va_start(ap, fmt);
+	printf("(%d,%d) request %llu + %u: ",
+	       MAJOR(t->device), MINOR(t->device),
+	       t->sector, t->bytes);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+}
+
 static void output_binary(void *buf, int len)
 {
 	if (dump_binary) {
@@ -988,6 +1004,10 @@ static struct io_track *find_track(struct per_dev_info *pdi, pid_t pid,
 		if (!iot->ppm)
 			iot->ppm = add_ppm_hash(pid, "unknown");
 		iot->sector = sector;
+		iot->allocation_time = -1ULL;
+		iot->queue_time = -1ULL;
+		iot->dispatch_time = -1ULL;
+		iot->completion_time = -1ULL;
 		track_rb_insert(pdi, iot);
 	}
 
@@ -1024,6 +1044,8 @@ static void log_track_getrq(struct per_dev_info *pdi, struct blk_io_trace *t)
 		return;
 
 	iot = find_track(pdi, t->pid, t->sector);
+	io_warn_unless(t, iot->allocation_time == -1ULL,
+		       "confused about %s time", "allocation");
 	iot->allocation_time = t->time;
 }
 
@@ -1039,6 +1061,8 @@ static void log_track_queue(struct per_dev_info *pdi, struct blk_io_trace *t)
 		return;
 
 	iot = find_track(pdi, t->pid, t->sector);
+	io_warn_unless(t, iot->dispatch_time == -1ULL,
+		       "confused about %s time", "dispatch");
 	iot->dispatch_time = t->time;
 }
 
@@ -1055,9 +1079,11 @@ static unsigned long long log_track_insert(struct per_dev_info *pdi,
 		return -1;
 
 	iot = find_track(pdi, t->pid, t->sector);
+	io_warn_unless(t, iot->queue_time == -1ULL,
+		       "confused about %s time", "queue");
 	iot->queue_time = t->time;
 
-	if (!iot->allocation_time)
+	if (iot->allocation_time == -1ULL)
 		return -1;
 
 	elapsed = iot->queue_time - iot->allocation_time;
@@ -1079,7 +1105,7 @@ static unsigned long long log_track_insert(struct per_dev_info *pdi,
 static unsigned long long log_track_issue(struct per_dev_info *pdi,
 					  struct blk_io_trace *t)
 {
-	unsigned long long elapsed;
+	unsigned long long elapsed = -1ULL;
 	struct io_track *iot;
 
 	if (!track_ios)
@@ -1096,10 +1122,13 @@ static unsigned long long log_track_issue(struct per_dev_info *pdi,
 		return -1;
 	}
 
+	io_warn_unless(t, iot->dispatch_time == -1ULL,
+		       "confused about %s time", "dispatch");
 	iot->dispatch_time = t->time;
-	elapsed = iot->dispatch_time - iot->queue_time;
+	if (iot->queue_time != -1ULL)
+		elapsed = iot->dispatch_time - iot->queue_time;
 
-	if (per_process_stats) {
+	if (elapsed != -1ULL && per_process_stats) {
 		struct per_process_info *ppi = find_ppi(iot->ppm->pid);
 		int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
@@ -1116,7 +1145,7 @@ static unsigned long long log_track_issue(struct per_dev_info *pdi,
 static unsigned long long log_track_complete(struct per_dev_info *pdi,
 					     struct blk_io_trace *t)
 {
-	unsigned long long elapsed;
+	unsigned long long elapsed = -1ULL;
 	struct io_track *iot;
 
 	if (!track_ios)
@@ -1131,10 +1160,13 @@ static unsigned long long log_track_complete(struct per_dev_info *pdi,
 		return -1;
 	}
 
+	io_warn_unless(t, iot->completion_time == -1ULL,
+		       "confused about %s time", "completion");
 	iot->completion_time = t->time;
-	elapsed = iot->completion_time - iot->dispatch_time;
+	if (iot->dispatch_time != -1ULL)
+		elapsed = iot->completion_time - iot->dispatch_time;
 
-	if (per_process_stats) {
+	if (elapsed != -1ULL && per_process_stats) {
 		struct per_process_info *ppi = find_ppi(iot->ppm->pid);
 		int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
-- 
2.25.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.