Skip to contentSkip to conversation

Recent changes (master)

PATCH Jens Axboe 2 participants 39 messages Mar 20, 2013 – Oct 22, 2021 Kbuild

lore
Share & tools
lore

Jens Axboe

author
#0 lore raw

The following changes since commit d6918c8832793b4205ed3bfede78c2f915c23385:

blktrace 1.0.5 (2012-02-27 08:22:17 +0100)

are available in the git repository at:
git://git.kernel.dk/blktrace.git master

Ivan Dyukov (1):
More accurate calculation of the total read/write values

 blkparse.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 blktrace.h |    4 +++
 2 files changed, 77 insertions(+), 14 deletions(-)

---

Diff of recent changes:

blkparse.c +73 -14
index a7ff0f7..a27b3ed 100644
@@ -1182,9 +1182,11 @@ static inline void __account_m(struct io_stats *ios, struct blk_io_trace *t,
 	if (rw) {
 		ios->mwrites++;
 		ios->mwrite_kb += t_kb(t);
+		ios->mwrite_b += t_b(t);
 	} else {
 		ios->mreads++;
 		ios->mread_kb += t_kb(t);
+		ios->mread_b += t_b(t);
 	}
 }
 
@@ -1206,9 +1208,11 @@ static inline void __account_pc_queue(struct io_stats *ios,
 	if (rw) {
 		ios->qwrites_pc++;
 		ios->qwrite_kb_pc += t_kb(t);
+		ios->qwrite_b_pc += t_b(t);
 	} else {
 		ios->qreads_pc++;
 		ios->qread_kb += t_kb(t);
+		ios->qread_b_pc += t_b(t);
 	}
 }
 
@@ -1230,9 +1234,11 @@ static inline void __account_pc_issue(struct io_stats *ios, int rw,
 	if (rw) {
 		ios->iwrites_pc++;
 		ios->iwrite_kb_pc += bytes >> 10;
+		ios->iwrite_b_pc += bytes & 1023;
 	} else {
 		ios->ireads_pc++;
 		ios->iread_kb_pc += bytes >> 10;
+		ios->iread_b_pc += bytes & 1023;
 	}
 }
 
@@ -1254,9 +1260,11 @@ static inline void __account_pc_requeue(struct io_stats *ios,
 	if (rw) {
 		ios->wrqueue_pc++;
 		ios->iwrite_kb_pc -= t_kb(t);
+		ios->iwrite_b_pc -= t_b(t);
 	} else {
 		ios->rrqueue_pc++;
 		ios->iread_kb_pc -= t_kb(t);
+		ios->iread_b_pc -= t_b(t);
 	}
 }
 
@@ -1298,9 +1306,11 @@ static inline void __account_queue(struct io_stats *ios, struct blk_io_trace *t,
 	if (rw) {
 		ios->qwrites++;
 		ios->qwrite_kb += t_kb(t);
+		ios->qwrite_b += t_b(t);
 	} else {
 		ios->qreads++;
 		ios->qread_kb += t_kb(t);
+		ios->qread_b += t_b(t);
 	}
 }
 
@@ -1321,9 +1331,11 @@ static inline void __account_c(struct io_stats *ios, int rw, int bytes)
 	if (rw) {
 		ios->cwrites++;
 		ios->cwrite_kb += bytes >> 10;
+		ios->cwrite_b += bytes & 1023;
 	} else {
 		ios->creads++;
 		ios->cread_kb += bytes >> 10;
+		ios->cread_b += bytes & 1023;
 	}
 }
 
@@ -1345,9 +1357,11 @@ static inline void __account_issue(struct io_stats *ios, int rw,
 	if (rw) {
 		ios->iwrites++;
 		ios->iwrite_kb += bytes >> 10;
+		ios->iwrite_b  += bytes & 1023;
 	} else {
 		ios->ireads++;
 		ios->iread_kb += bytes >> 10;
+		ios->iread_b  += bytes & 1023;
 	}
 }
 
@@ -1389,9 +1403,11 @@ static inline void __account_requeue(struct io_stats *ios,
 	if (rw) {
 		ios->wrqueue++;
 		ios->iwrite_kb -= t_kb(t);
+		ios->iwrite_b -= t_b(t);
 	} else {
 		ios->rrqueue++;
 		ios->iread_kb -= t_kb(t);
+		ios->iread_b -= t_b(t);
 	}
 }
 
@@ -1654,26 +1670,55 @@ static void dump_io_stats(struct per_dev_info *pdi, struct io_stats *ios,
 
 	fprintf(ofp, "%s\n", msg);
 
-	fprintf(ofp, " Reads Queued:    %s, %siB\t", size_cnv(x, ios->qreads, 0), size_cnv(y, ios->qread_kb, 1));
-	fprintf(ofp, " Writes Queued:    %s, %siB\n", size_cnv(x, ios->qwrites, 0), size_cnv(y, ios->qwrite_kb, 1));
-	fprintf(ofp, " Read Dispatches: %s, %siB\t", size_cnv(x, ios->ireads, 0), size_cnv(y, ios->iread_kb, 1));
-	fprintf(ofp, " Write Dispatches: %s, %siB\n", size_cnv(x, ios->iwrites, 0), size_cnv(y, ios->iwrite_kb, 1));
+	fprintf(ofp, " Reads Queued:    %s, %siB\t",
+			size_cnv(x, ios->qreads, 0),
+			size_cnv(y, ios->qread_kb + (ios->qread_b>>10), 1));
+	fprintf(ofp, " Writes Queued:    %s, %siB\n",
+			size_cnv(x, ios->qwrites, 0),
+			size_cnv(y, ios->qwrite_kb + (ios->qwrite_b>>10), 1));
+	fprintf(ofp, " Read Dispatches: %s, %siB\t",
+			size_cnv(x, ios->ireads, 0),
+			size_cnv(y, ios->iread_kb + (ios->iread_b>>10), 1));
+	fprintf(ofp, " Write Dispatches: %s, %siB\n",
+			size_cnv(x, ios->iwrites, 0),
+			size_cnv(y, ios->iwrite_kb + (ios->iwrite_b>>10), 1));
 	fprintf(ofp, " Reads Requeued:  %s\t\t", size_cnv(x, ios->rrqueue, 0));
 	fprintf(ofp, " Writes Requeued:  %s\n", size_cnv(x, ios->wrqueue, 0));
-	fprintf(ofp, " Reads Completed: %s, %siB\t", size_cnv(x, ios->creads, 0), size_cnv(y, ios->cread_kb, 1));
-	fprintf(ofp, " Writes Completed: %s, %siB\n", size_cnv(x, ios->cwrites, 0), size_cnv(y, ios->cwrite_kb, 1));
-	fprintf(ofp, " Read Merges:     %s, %siB\t", size_cnv(x, ios->mreads, 0), size_cnv(y, ios->mread_kb, 1));
-	fprintf(ofp, " Write Merges:     %s, %siB\n", size_cnv(x, ios->mwrites, 0), size_cnv(y, ios->mwrite_kb, 1));
+	fprintf(ofp, " Reads Completed: %s, %siB\t",
+			size_cnv(x, ios->creads, 0),
+			size_cnv(y, ios->cread_kb + (ios->cread_b>>10), 1));
+	fprintf(ofp, " Writes Completed: %s, %siB\n",
+			size_cnv(x, ios->cwrites, 0),
+			size_cnv(y, ios->cwrite_kb + (ios->cwrite_b>>10), 1));
+	fprintf(ofp, " Read Merges:     %s, %siB\t",
+			size_cnv(x, ios->mreads, 0),
+			size_cnv(y, ios->mread_kb + (ios->mread_b>>10), 1));
+	fprintf(ofp, " Write Merges:     %s, %siB\n",
+			size_cnv(x, ios->mwrites, 0),
+			size_cnv(y, ios->mwrite_kb + (ios->mwrite_b>>10), 1));
 	if (pdi) {
 		fprintf(ofp, " Read depth:      %'8u%8c\t", pdi->max_depth[0], ' ');
 		fprintf(ofp, " Write depth:      %'8u\n", pdi->max_depth[1]);
 	}
 	if (ios->qreads_pc || ios->qwrites_pc || ios->ireads_pc || ios->iwrites_pc ||
 	    ios->rrqueue_pc || ios->wrqueue_pc || ios->creads_pc || ios->cwrites_pc) {
-		fprintf(ofp, " PC Reads Queued: %s, %siB\t", size_cnv(x, ios->qreads_pc, 0), size_cnv(y, ios->qread_kb_pc, 1));
-		fprintf(ofp, " PC Writes Queued: %s, %siB\n", size_cnv(x, ios->qwrites_pc, 0), size_cnv(y, ios->qwrite_kb_pc, 1));
-		fprintf(ofp, " PC Read Disp.:   %s, %siB\t", size_cnv(x, ios->ireads_pc, 0), size_cnv(y, ios->iread_kb_pc, 1));
-		fprintf(ofp, " PC Write Disp.:   %s, %siB\n", size_cnv(x, ios->iwrites_pc, 0), size_cnv(y, ios->iwrite_kb_pc, 1));
+		fprintf(ofp, " PC Reads Queued: %s, %siB\t",
+			size_cnv(x, ios->qreads_pc, 0),
+			size_cnv(y,
+				ios->qread_kb_pc + (ios->qread_b_pc>>10), 1));
+		fprintf(ofp, " PC Writes Queued: %s, %siB\n",
+			size_cnv(x, ios->qwrites_pc, 0),
+			size_cnv(y,
+				ios->qwrite_kb_pc + (ios->qwrite_b_pc>>10), 1));
+		fprintf(ofp, " PC Read Disp.:   %s, %siB\t",
+			size_cnv(x, ios->ireads_pc, 0),
+			size_cnv(y,
+				ios->iread_kb_pc + (ios->iread_b_pc>>10), 1));
+		fprintf(ofp, " PC Write Disp.:   %s, %siB\n",
+			size_cnv(x, ios->iwrites_pc, 0),
+			size_cnv(y,
+				ios->iwrite_kb_pc + (ios->iwrite_b_pc>>10),
+				1));
 		fprintf(ofp, " PC Reads Req.:   %s\t\t", size_cnv(x, ios->rrqueue_pc, 0));
 		fprintf(ofp, " PC Writes Req.:   %s\n", size_cnv(x, ios->wrqueue_pc, 0));
 		fprintf(ofp, " PC Reads Compl.: %s\t\t", size_cnv(x, ios->creads_pc, 0));
@@ -1808,6 +1853,14 @@ static void show_device_and_cpu_stats(void)
 			total.iwrite_kb += ios->iwrite_kb;
 			total.mread_kb += ios->mread_kb;
 			total.mwrite_kb += ios->mwrite_kb;
+			total.qread_b += ios->qread_b;
+			total.qwrite_b += ios->qwrite_b;
+			total.cread_b += ios->cread_b;
+			total.cwrite_b += ios->cwrite_b;
+			total.iread_b += ios->iread_b;
+			total.iwrite_b += ios->iwrite_b;
+			total.mread_b += ios->mread_b;
+			total.mwrite_b += ios->mwrite_b;
 
 			total.qreads_pc += ios->qreads_pc;
 			total.qwrites_pc += ios->qwrites_pc;
@@ -1821,6 +1874,10 @@ static void show_device_and_cpu_stats(void)
 			total.qwrite_kb_pc += ios->qwrite_kb_pc;
 			total.iread_kb_pc += ios->iread_kb_pc;
 			total.iwrite_kb_pc += ios->iwrite_kb_pc;
+			total.qread_b_pc += ios->qread_b_pc;
+			total.qwrite_b_pc += ios->qwrite_b_pc;
+			total.iread_b_pc += ios->iread_b_pc;
+			total.iwrite_b_pc += ios->iwrite_b_pc;
 
 			total.timer_unplugs += ios->timer_unplugs;
 			total.io_unplugs += ios->io_unplugs;
@@ -1841,8 +1898,10 @@ static void show_device_and_cpu_stats(void)
 		wrate = rrate = 0;
 		msec = (pdi->last_reported_time - pdi->first_reported_time) / 1000000;
 		if (msec) {
-			rrate = 1000 * total.cread_kb / msec;
-			wrate = 1000 * total.cwrite_kb / msec;
+			rrate = ((1000 * total.cread_kb) + total.cread_b) /
+									msec;
+			wrate = ((1000 * total.cwrite_kb) + total.cwrite_b) /
+									msec;
 		}
 
 		fprintf(ofp, "\nThroughput (R/W): %'LuKiB/s / %'LuKiB/s\n",
blktrace.h +4 -0
index 5da6dbc..380aec7 100644
@@ -23,6 +23,7 @@
 
 #define t_sec(t)	((t)->bytes >> 9)
 #define t_kb(t)		((t)->bytes >> 10)
+#define t_b(t)		((t)->bytes & 1023)
 
 typedef __u32 u32;
 typedef __u8 u8;
@@ -31,11 +32,14 @@ struct io_stats {
 	unsigned long qreads, qwrites, creads, cwrites, mreads, mwrites;
 	unsigned long ireads, iwrites, rrqueue, wrqueue;
 	unsigned long long qread_kb, qwrite_kb, cread_kb, cwrite_kb;
+	unsigned long long qread_b, qwrite_b, cread_b, cwrite_b;
 	unsigned long long iread_kb, iwrite_kb;
 	unsigned long long mread_kb, mwrite_kb;
+	unsigned long long mread_b, mwrite_b, iread_b, iwrite_b;
 	unsigned long qreads_pc, qwrites_pc, ireads_pc, iwrites_pc;
 	unsigned long rrqueue_pc, wrqueue_pc, creads_pc, cwrites_pc;
 	unsigned long long qread_kb_pc, qwrite_kb_pc, iread_kb_pc, iwrite_kb_pc;
+	unsigned long long qread_b_pc, qwrite_b_pc, iread_b_pc, iwrite_b_pc;
 	unsigned long io_unplugs, timer_unplugs;
 };
 
author
#1 lore raw

The following changes since commit cd0ae0f6bc3d72e89d0b258aa2040437b75d4ef2:

More accurate calculation of the total read/write values (2013-03-19 08:16:27 -0600)

are available in the git repository at:
git://git.kernel.dk/blktrace.git master

Nathan Zimmer (5):
verify_blkparse: Change max_cpus to deal with systems larger the 512
btreplay: Machines are now large enough that holes need to be dealt with
btreplay: use sysconf to get the number of configured cpus
blktrace: use number of configured cpus instead of online cpus blktrace blkreplay: convert to use a dynamic cpu_set_t

 blktrace.c          |   20 +++++++++++++-------
 btreplay/btreplay.c |   51 +++++++++++++++++++++++++++++++++++----------------
 verify_blkparse.c   |   23 +++++++++++++++++++----
 3 files changed, 67 insertions(+), 27 deletions(-)

---

Diff of recent changes:

blktrace.c +13 -7
index 89aaaac..7e64c94 100644
@@ -621,13 +621,19 @@ static void dpp_free(struct devpath *dpp)
 
 static int lock_on_cpu(int cpu)
 {
-	cpu_set_t cpu_mask;
-
-	CPU_ZERO(&cpu_mask);
-	CPU_SET(cpu, &cpu_mask);
-	if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) < 0)
+	cpu_set_t * cpu_mask;
+	size_t size;
+	cpu_mask = CPU_ALLOC(ncpus);
+	size = CPU_ALLOC_SIZE(ncpus);
+
+	CPU_ZERO_S(size, cpu_mask);
+	CPU_SET_S(cpu, size, cpu_mask);
+	if (sched_setaffinity(0, size, cpu_mask) < 0) {
+		CPU_FREE(cpu_mask);		
 		return errno;
+	}
 
+	CPU_FREE(cpu_mask);		
 	return 0;
 }
 
@@ -2656,9 +2662,9 @@ int main(int argc, char *argv[])
 
 	setlocale(LC_NUMERIC, "en_US");
 	pagesize = getpagesize();
-	ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+	ncpus = sysconf(_SC_NPROCESSORS_CONF);
 	if (ncpus < 0) {
-		fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed %d/%s\n",
+		fprintf(stderr, "sysconf(_SC_NPROCESSORS_CONF) failed %d/%s\n",
 			errno, strerror(errno));
 		ret = 1;
 		goto out;
btreplay/btreplay.c +35 -16

79 lines not on this page · raw message

verify_blkparse.c +19 -4
index aae8d7c..5689f43 100644
@@ -3,18 +3,33 @@
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
-
-#define MAX_CPUS	(512)
+#include <errno.h>
 
 int main(int argc, char *argv[])
 {
 	double this_time, last_time;
 	char line[256], last_line[256], *p;
 	int major, minor, cpu, nr, alias;
+	long  MAX_CPUS;
 	unsigned long long total_entries;
-	unsigned int last_seq[MAX_CPUS], seq;
+	unsigned int *last_seq;
+	unsigned int seq;
 	FILE *f;
 
+#ifdef _SC_NPROCESSORS_CONF
+	MAX_CPUS = sysconf(_SC_NPROCESSORS_CONF);
+	if (MAX_CPUS < 1)
+	{
+		fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", 
+			strerror (errno));
+		fprintf(stderr, "Assuming 1024\n");
+		MAX_CPUS = 1024;
+  	}
+#else
+	MAX_CPUS = CPU_SETSIZE;
+#endif 
+	
+	last_seq = malloc( sizeof(unsigned int) * MAX_CPUS );
 	for (nr = 0; nr < MAX_CPUS; nr++)
 		last_seq[nr] = -1;
 
@@ -33,7 +48,7 @@ int main(int argc, char *argv[])
 	alias = nr = 0;
 	total_entries = 0;
 	while ((p = fgets(line, sizeof(line), f)) != NULL) {
-		if (sscanf(p, "%3d,%3d %2d %8d %lf", &major, &minor, &cpu, &seq, &this_time) != 5)
+		if (sscanf(p, "%3d,%3d %5d %8d %lf", &major, &minor, &cpu, &seq, &this_time) != 5)
 			break;
 
 		if (this_time < last_time) {
author
#2 lore raw
In reply to Jens Axboe

The following changes since commit 0a915aabe88ff98786a88f30d2e062ef34d0826c:

blktrace blkreplay: convert to use a dynamic cpu_set_t (2013-08-01 12:13:26 -0600)

are available in the git repository at:
git://git.kernel.dk/blktrace.git master

Eiichi Tsukata (1):
blktrace bno_plot.py: output comprehensive message when gnuplot not found

 btt/bno_plot.py |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

---

Diff of recent changes:

btt/bno_plot.py +2 -3
index 19dfdfd..aa92480 100644
@@ -114,13 +114,12 @@ if __name__ = '__main__':
 
 	pid = os.fork()
 	if pid = 0:
-		cmd = '/usr/bin/gnuplot %s/plot.cmds -' % tmpdir
+		cmd = 'gnuplot %s/plot.cmds -' % tmpdir
 
 		if verbose: print 'Executing %s' % cmd
 
-		cmd = cmd.split(None)
 		os.chdir(tmpdir)
-		os.execvp(cmd[0], cmd)
+		os.system(cmd)
 		sys.exit(1)
 
 	os.waitpid(pid, 0)
#3 lore raw
In reply to Jens Axboe

The following changes since commit 3726f669cd305741e35ae759e0b21f3b04084e4e:

blktrace bno_plot.py: output comprehensive message when gnuplot not found (2013-12-03 19:25:21 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to ce9ded7165b846598b28107ceb2864ae1ad4b652:

remove unused barrier.h (2014-04-11 07:45:54 -0600)

----------------------------------------------------------------
Riku Voipio (1):
remove unused barrier.h

 barrier.h |   33 ---------------------------------
 1 file changed, 33 deletions(-)
 delete mode 100644 barrier.h

---

Diff of recent changes:

barrier.h deleted +0 -33
deleted file mode 100644
index 14d06b5..0000000
@@ -1,33 +0,0 @@
-#ifndef BARRIER_H
-#define BARRIER_H
-
-#if defined(__ia64__)
-  #define store_barrier()         asm volatile ("mf" ::: "memory")
-#elif defined(__x86_64__)
-  #define store_barrier()         asm volatile("sfence" ::: "memory")
-#elif defined(__i386__)
-  #define store_barrier()         asm volatile ("": : :"memory")
-#elif defined(__ppc__) || defined(__powerpc__)
-  #define store_barrier()         asm volatile ("eieio" : : : "memory")
-#elif defined(__s390__) || defined(__s390x__)
-  #define store_barrier()         asm volatile ("bcr 15,0" : : : "memory")
-#elif defined(__alpha__)
-  #define store_barrier()         asm volatile("wmb": : :"memory")
-#elif defined(__hppa__)
-  #define store_barrier()         asm volatile("":::"memory")
-#elif defined(__sparc__)
-  #define store_barrier()         asm volatile("":::"memory")
-#elif defined(__m68000__) || defined(__m68k__) || defined(mc68000) || defined(_M_M68K)
-  #define store_barrier()         asm volatile("":::"memory")
-#elif defined(__mips__)  /* also mipsel */
-  #define store_barrier()         do { } while(0)
-#elif defined(__arm__)
-  /* taken from linux/arch/arm/kernel/entry-armv.S, thanks to pbrook! */
-  typedef void (__kernel_dmb_t)(void);
-  #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
-  #define store_barrier()        __kernel_dmb()
-#else
-  #error Define store_barrier() for your CPU
-#endif
-
-#endif
#4 lore raw
In reply to Jens Axboe

The following changes since commit ce9ded7165b846598b28107ceb2864ae1ad4b652:

remove unused barrier.h (2014-04-11 07:45:54 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 838361c6cfb1319eadd59daaf9074dcdb92746e6:

signal condition variable at end of stop_tracers (2014-09-08 08:15:58 -0600)

----------------------------------------------------------------
Robert Schiele (1):
signal condition variable at end of stop_tracers

 blktrace.c |    1 +
 1 file changed, 1 insertion(+)

---

Diff of recent changes:

blktrace.c +1 -0
index 7e64c94..3c8fb4c 100644
@@ -1913,6 +1913,7 @@ static void stop_tracers(void)
 		struct tracer *tp = list_entry(p, struct tracer, head);
 		tp->is_done = 1;
 	}
+	pthread_cond_broadcast(&mt_cond);
 }
 
 static void del_tracers(void)
#5 lore raw
In reply to Jens Axboe

The following changes since commit fe311e7c01593444f397d6d012ec212c4b22f514:

Makefile: ensure that iowatcher gets cleaned (2014-09-24 14:49:04 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 2cf87e6092da7b36d5ef10c830ddf12d9e18121d:

iowatcher: wrap system() in a checker function (2014-09-25 15:17:06 -0600)

----------------------------------------------------------------
Andrew Price (4):
iowatcher: Add iowatcher to .gitignore
iowatcher: Move iowatcher.1 into doc directory
iowatcher: Remove iowatcher/README
Add iowatcher requirements to README

Chris Mason (2):
iowatcher: fixup the Makefile
iowatcher: check the return value from write()

Jens Axboe (3):
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/blktrace
Merge branch 'for-upstream' of https://github.com/andyprice/blktrace
iowatcher: wrap system() in a checker function

 .gitignore                     |    1 +
 README                         |    2 +
 {iowatcher => doc}/iowatcher.1 |    0
 iowatcher/Makefile             |    2 +-
 iowatcher/README               |   97 ------------------------------------
 iowatcher/main.c               |   20 ++++++--
 iowatcher/plot.c               |  107 ++++++++++++++++++++++------------------
 7 files changed, 77 insertions(+), 152 deletions(-)
 rename {iowatcher => doc}/iowatcher.1 (100%)
 delete mode 100644 iowatcher/README

---

Diff of recent changes:

.gitignore +1 -0
index 2436e34..87a5d2d 100644
@@ -11,3 +11,4 @@ verify_blkparse
 btt/btt
 btt/doc/btt.pdf
 doc/blktrace.pdf
+iowatcher/iowatcher
README +2 -0
index f52f48d..d7d1fbf 100644
@@ -31,6 +31,8 @@ your browser to:
 
 http://git.kernel.dk/
 
+A blktrace visualization tool, iowatcher, was added to blktrace in version
+1.1.0. It requires librsvg and either png2theora or ffmpeg to generate movies.
 
 Usage
 -----
doc/iowatcher.1 new file +162 -0

162 lines not on this page · raw message

iowatcher/Makefile +1 -1
index e0f34b2..3551ea0 100644
@@ -1,5 +1,5 @@
 CC      = gcc
-CFLAGS  = -Wall -O0 -g -W
+CFLAGS  = -Wall -O2 -g -W -Wunused-result
 ALL_CFLAGS = $(CFLAGS) -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITSd
 
 PROGS = iowatcher
iowatcher/README deleted +0 -97

97 lines not on this page · raw message

iowatcher/iowatcher.1 deleted +0 -162

162 lines not on this page · raw message

iowatcher/main.c +15 -5
index cbf6c9a..2797afb 100644
@@ -1016,12 +1016,22 @@ static void plot_queue_depth(struct plot *plot, unsigned int min_seconds,
 	total_graphs_written++;
 }
 
+static void system_check(const char *cmd)
+{
+	if (system(cmd) < 0) {
+		int err = errno;
+
+		fprintf(stderr, "system exec failed (%d): %s\n", err, cmd);
+		exit(1);
+	}
+}
+
 static void convert_movie_files(char *movie_dir)
 {
 	fprintf(stderr, "Converting svg files in %s\n", movie_dir);
 	snprintf(line, line_len, "find %s -name \\*.svg | xargs -I{} -n 1 -P 8 rsvg-convert -o {}.png {}",
 		 movie_dir);
-	system(line);
+	system_check(line);
 }
 
 static void mencode_movie(char *movie_dir)
@@ -1030,7 +1040,7 @@ static void mencode_movie(char *movie_dir)
 	snprintf(line, line_len, "ffmpeg -r 20 -y -i %s/%%10d-%s.svg.png -b:v 250k "
 		 "-vcodec %s %s", movie_dir, output_filename, ffmpeg_codec,
 		 output_filename);
-	system(line);
+	system_check(line);
 }
 
 static void tencode_movie(char *movie_dir)
@@ -1038,7 +1048,7 @@ static void tencode_movie(char *movie_dir)
 	fprintf(stderr, "Creating movie %s with png2theora\n", movie_dir);
 	snprintf(line, line_len, "png2theora -o %s %s/%%010d-%s.svg.png",
 			output_filename, movie_dir, output_filename);
-	system(line);
+	system_check(line);
 }
 
 static void encode_movie(char *movie_dir)
@@ -1060,10 +1070,10 @@ static void cleanup_movie(char *movie_dir)
 	}
 	fprintf(stderr, "Removing movie dir %s\n", movie_dir);
 	snprintf(line, line_len, "rm %s/*", movie_dir);
-	system(line);
+	system_check(line);
 
 	snprintf(line, line_len, "rmdir %s", movie_dir);
-	system(line);
+	system_check(line);
 }
 
 static void plot_io_movie(struct plot *plot)
iowatcher/plot.c +58 -49

311 lines not on this page · raw message

#6 lore raw
In reply to Jens Axboe

The following changes since commit 2cf87e6092da7b36d5ef10c830ddf12d9e18121d:

iowatcher: wrap system() in a checker function (2014-09-25 15:17:06 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 88d38b4d0a5b33332fa80d7028a87c0717bb5d75:

Refer to sda instead of hda in man pages (2015-02-18 08:50:02 -0800)

----------------------------------------------------------------
Olaf Hering (1):
Refer to sda instead of hda in man pages

 doc/blkparse.1 |    2 +-
 doc/blktrace.8 |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

---

Diff of recent changes:

doc/blkparse.1 +1 -1
index 9193dbe..be9b34b 100644
@@ -530,7 +530,7 @@ device and sector offset.
 
 
 .SH EXAMPLES
-To trace the i/o on the device \fI/dev/hda\fB and parse the output to human
+To trace the i/o on the device \fI/dev/sda\fB and parse the output to human
 readable form, use the following command:
 
     % blktrace \-d /dev/sda \-o \- | blkparse \-i \-
doc/blktrace.8 +1 -1
index b5e69b7..df464be 100644
@@ -236,7 +236,7 @@ sends the command data block as a payload so that blkparse can decode it.
 
 
 .SH EXAMPLES
-To trace the i/o on the device \fI/dev/hda\fR and parse the output to human
+To trace the i/o on the device \fI/dev/sda\fR and parse the output to human
 readable form, use the following command:
 
     % blktrace \-d /dev/sda \-o \- | blkparse \-i \-
#7 lore raw
In reply to Jens Axboe

The following changes since commit 88d38b4d0a5b33332fa80d7028a87c0717bb5d75:

Refer to sda instead of hda in man pages (2015-02-18 08:50:02 -0800)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 2564a6029e55d6a0507ebb28a5a01f5dffb0bd56:

btreplay: Fix typo in scaling up the dynamic cpu set size. (2015-08-20 08:58:08 -0700)

----------------------------------------------------------------
Josef Cejka (1):
btreplay: Fix typo in scaling up the dynamic cpu set size.

 btreplay/btreplay.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

btreplay/btreplay.c +1 -1
index 5444010..f762279 100644
@@ -516,7 +516,7 @@ realloc:
 	if (sched_getaffinity(getpid(), size, cpus)) {
 		if( errno = EINVAL && nrcpus < (4096<<4) ) {
 			CPU_FREE(cpus);
-			nrcpus <= 1;
+			nrcpus <<= 1;
 			goto realloc;
 		}
 		fatal("sched_getaffinity", ERR_SYSCALL, "Can't get CPU info\n");
#8 lore raw
In reply to Jens Axboe

The following changes since commit 2564a6029e55d6a0507ebb28a5a01f5dffb0bd56:

btreplay: Fix typo in scaling up the dynamic cpu set size. (2015-08-20 08:58:08 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to dd093eb1c48e0d86b835758b96a9886fb7773aa4:

Fix warnings on newer gcc (2015-09-15 08:48:06 -0600)

----------------------------------------------------------------
Jens Axboe (1):
Fix warnings on newer gcc

Khem Raj (1):
include sys/types.h for dev_t definition

 blkiomon.c          | 2 +-
 blktrace.h          | 1 +
 btreplay/btreplay.c | 4 ++--
 3 files changed, 4 insertions(+), 3 deletions(-)

---

Diff of recent changes:

blkiomon.c +1 -1
index a895f65..f8b0c9d 100644
@@ -198,7 +198,7 @@ static struct dstat *blkiomon_find_dstat(struct rb_search *search, __u32 device)
 static struct dstat *blkiomon_get_dstat(__u32 device)
 {
 	struct dstat *dstat;
-	struct rb_search search;
+	struct rb_search search = { 0, };
 
 	pthread_mutex_lock(&dstat_mutex);
 
blktrace.h +1 -0
index 380aec7..944fc08 100644
@@ -5,6 +5,7 @@
 #include <limits.h>
 #include <byteswap.h>
 #include <endian.h>
+#include <sys/types.h>
 
 #include "blktrace_api.h"
 #include "rbtree.h"
btreplay/btreplay.c +2 -2
index f762279..2a1e1cc 100644
@@ -646,7 +646,7 @@ static void find_input_devs(char *idir)
 static void read_map_devs(char *file_name)
 {
 	FILE *fp;
-	char *from_dev, *to_dev;
+	char from_dev[256], to_dev[256];
 
 	fp = fopen(file_name, "r");
 	if (!fp) {
@@ -654,7 +654,7 @@ static void read_map_devs(char *file_name)
 		/*NOTREACHED*/
 	}
 
-	while (fscanf(fp, "%as %as", &from_dev, &to_dev) = 2) {
+	while (fscanf(fp, "%s %s", from_dev, to_dev) = 2) {
 		struct map_dev *mdp = malloc(sizeof(*mdp));
 
 		mdp->from_dev = from_dev;
#9 lore raw
In reply to Jens Axboe

The following changes since commit dd093eb1c48e0d86b835758b96a9886fb7773aa4:

Fix warnings on newer gcc (2015-09-15 08:48:06 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 8a1209713563b4dedea962909c18b941fb09d01a:

Add the "-a discard" filter option to the blktrace.8 man page (2016-01-08 11:46:03 -0700)

----------------------------------------------------------------
John Groves (1):
Add the "-a discard" filter option to the blktrace.8 man page

 doc/blktrace.8 | 2 ++
 1 file changed, 2 insertions(+)

---

Diff of recent changes:

doc/blktrace.8 +2 -0
index df464be..68f5e15 100644
@@ -202,6 +202,8 @@ line options.
 .br
 \fIcomplete\fR: completed by driver
 .br
+\fIdiscard\fR: discard / trim traces
+.br
 \fIfs\fR: requests 
 .br
 \fIissue\fR: issued to driver 
#10 lore raw
In reply to Jens Axboe

The following changes since commit 8a1209713563b4dedea962909c18b941fb09d01a:

Add the "-a discard" filter option to the blktrace.8 man page (2016-01-08 11:46:03 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 80c4041b2e7a7d5afb75df563bf51bb27773c095:

blktrace: Use number of online CPUs (2016-02-09 08:17:50 -0700)

----------------------------------------------------------------
Abutalib Aghayev (1):
blktrace: Use number of online CPUs

 blktrace.c          | 4 ++--
 btreplay/btreplay.c | 4 ++--
 verify_blkparse.c   | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

---

Diff of recent changes:

blktrace.c +2 -2
index 3c8fb4c..b445524 100644
@@ -2663,9 +2663,9 @@ int main(int argc, char *argv[])
 
 	setlocale(LC_NUMERIC, "en_US");
 	pagesize = getpagesize();
-	ncpus = sysconf(_SC_NPROCESSORS_CONF);
+	ncpus = sysconf(_SC_NPROCESSORS_ONLN);
 	if (ncpus < 0) {
-		fprintf(stderr, "sysconf(_SC_NPROCESSORS_CONF) failed %d/%s\n",
+		fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed %d/%s\n",
 			errno, strerror(errno));
 		ret = 1;
 		goto out;
btreplay/btreplay.c +2 -2
index 2a1e1cc..6d19564 100644
@@ -502,8 +502,8 @@ static inline void start_iter(void)
  */
 static void get_ncpus(void)
 {
-#ifdef _SC_NPROCESSORS_CONF
-	ncpus = sysconf(_SC_NPROCESSORS_CONF);
+#ifdef _SC_NPROCESSORS_ONLN
+	ncpus = sysconf(_SC_NPROCESSORS_ONLN);
 #else
 	int nrcpus = 4096;
 	cpu_set_t * cpus;
verify_blkparse.c +2 -2
index 5689f43..3f3e92a 100644
@@ -16,8 +16,8 @@ int main(int argc, char *argv[])
 	unsigned int seq;
 	FILE *f;
 
-#ifdef _SC_NPROCESSORS_CONF
-	MAX_CPUS = sysconf(_SC_NPROCESSORS_CONF);
+#ifdef _SC_NPROCESSORS_ONLN
+	MAX_CPUS = sysconf(_SC_NPROCESSORS_ONLN);
 	if (MAX_CPUS < 1)
 	{
 		fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", 
#11 lore raw
In reply to Jens Axboe

The following changes since commit 80c4041b2e7a7d5afb75df563bf51bb27773c095:

blktrace: Use number of online CPUs (2016-02-09 08:17:50 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to cbd4bc0a3f6386cd000cb842b9f1f6325e301623:

btreplay: remove timestamps (2016-04-25 08:54:34 -0600)

----------------------------------------------------------------
Olaf Hering (1):
btreplay: remove timestamps

Roman Pen (3):
btreplay: fix memory corruption caused by CPU_ZERO_S
btreplay: fix sched_{set|get}affinity
btreplay: make Ctrl-C work

 btreplay/btrecord.c |  3 ---
 btreplay/btreplay.c | 15 ++++++---------
 2 files changed, 6 insertions(+), 12 deletions(-)

---

Diff of recent changes:

btreplay/btrecord.c +0 -3
index 3646257..a07ca07 100644
@@ -18,8 +18,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-static char build_date[] = __DATE__ " at "__TIME__;
-
 #include <assert.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -449,7 +447,6 @@ void handle_args(int argc, char *argv[])
 		case 'V':
 			fprintf(stderr, "btrecord -- version %s\n", 
 				my_btversion);
-			fprintf(stderr, "            Built on %s\n", build_date);
 			exit(0);
 			/*NOTREACHED*/
 
btreplay/btreplay.c +6 -9
index 6d19564..edaf81f 100644
@@ -18,8 +18,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-static char build_date[] = __DATE__ " at "__TIME__;
-
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -275,7 +273,7 @@ static inline int is_send_done(struct thr_info *tip)
  */
 static inline int is_reap_done(struct thr_info *tip)
 {
-	return tip->send_done && tip->naios_out = 0;
+	return signal_done || (tip->send_done && tip->naios_out = 0);
 }
 
 /**
@@ -513,7 +511,7 @@ realloc:
 	size = CPU_ALLOC_SIZE(nrcpus);
 	CPU_ZERO_S(size, cpus);
 
-	if (sched_getaffinity(getpid(), size, cpus)) {
+	if (sched_getaffinity(0, size, cpus)) {
 		if( errno = EINVAL && nrcpus < (4096<<4) ) {
 			CPU_FREE(cpus);
 			nrcpus <<= 1;
@@ -550,18 +548,19 @@ static void pin_to_cpu(struct thr_info *tip)
 
 	assert(0 <= tip->cpu && tip->cpu < ncpus);
 
-	CPU_ZERO_S(ncpus, cpus);
+	CPU_ZERO_S(size, cpus);
 	CPU_SET_S(tip->cpu, size, cpus);
-	if (sched_setaffinity(getpid(), size, cpus)) {
+	if (sched_setaffinity(0, size, cpus)) {
 		fatal("sched_setaffinity", ERR_SYSCALL, "Failed to pin CPU\n");
 		/*NOTREACHED*/
 	}
+	assert(tip->cpu = sched_getcpu());
 
 	if (verbose > 1) {
 		int i;
 		cpu_set_t *now = CPU_ALLOC(ncpus);
 
-		(void)sched_getaffinity(getpid(), size, now);
+		(void)sched_getaffinity(0, size, now);
 		fprintf(tip->vfp, "Pinned to CPU %02d ", tip->cpu);
 		for (i = 0; i < ncpus; i++)
 			fprintf(tip->vfp, "%1d", CPU_ISSET_S(i, size, now));
@@ -1558,8 +1557,6 @@ static void handle_args(int argc, char *argv[])
 		case 'V':
 			fprintf(stderr, "btreplay -- version %s\n", 
 				my_btversion);
-			fprintf(stderr, "            Built on %s\n", 
-				build_date);
 			exit(0);
 			/*NOTREACHED*/
 
#12 lore raw
In reply to Jens Axboe

The following changes since commit cbd4bc0a3f6386cd000cb842b9f1f6325e301623:

btreplay: remove timestamps (2016-04-25 08:54:34 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to d1422556dbff03e982aeb2faf5893b4363621bee:

btt/unplug_hist: fix bad memset (2016-05-03 08:34:50 -0600)

----------------------------------------------------------------
Jens Axboe (1):
btt/unplug_hist: fix bad memset

 btt/unplug_hist.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

---

Diff of recent changes:

btt/unplug_hist.c +3 -3
index 89995de..be16b69 100644
@@ -34,11 +34,11 @@ void *unplug_hist_alloc(struct d_info *dip)
 {
 	struct hist_bkt *hbp;
 
-	if (unplug_hist_name = NULL) return NULL;
+	if (unplug_hist_name = NULL)
+		return NULL;
 
-	hbp = malloc(sizeof(*hbp));
+	hbp = calloc(1, sizeof(*hbp));
 	hbp->dip = dip;
-	memset(hbp->hist, 0, NBKTS * sizeof(int));
 
 	return hbp;
 }
#13 lore raw
In reply to Jens Axboe

The following changes since commit d1422556dbff03e982aeb2faf5893b4363621bee:

btt/unplug_hist: fix bad memset (2016-05-03 08:34:50 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 7644909627859a9d9d837df8b2ecf21a169f0ff0:

Fixup graph name in help text (2016-05-05 09:20:18 -0600)

----------------------------------------------------------------
Jan Kara (9):
Better max estimate for line graphs
Use maximum over all traces for queue depth
Process notify events outside of given interval
iowatcher: Use queue events if issue not available
btt: Replace overlapping IO
Zero sectors are strange
Don't prepend blktrace destination dir if we didn't run blktrace Separate prefix in legend with space
Fixup graph name in help text

 btt/dip_rb.c         |  6 ++++--
 iowatcher/blkparse.c | 16 ++++++++++++--
 iowatcher/main.c     | 59 +++++++++++++++++++++++++++++++++-------------------
 iowatcher/plot.c     | 28 +++++++++++++++++++++----
 iowatcher/plot.h     |  1 +
 5 files changed, 81 insertions(+), 29 deletions(-)

---

Diff of recent changes:

btt/dip_rb.c +4 -2
index 867a97b..2aa7ffc 100644
@@ -37,8 +37,10 @@ int rb_insert(struct rb_root *root, struct io *iop)
 			p = &(*p)->rb_left;
 		else if (s > __s)
 			p = &(*p)->rb_right;
-		else
-			return 0;
+		else {
+			rb_replace_node(parent, &iop->rb_node, root);
+			return 1;
+		}
 	}
 
 	rb_link_node(&iop->rb_node, parent, p);
iowatcher/blkparse.c +14 -2
index ef33d5b..c7d1d65 100644
@@ -1097,8 +1097,19 @@ void add_pending_io(struct trace *trace, struct graph_line_data *gld)
 		return;
 
 	if (action = __BLK_TA_QUEUE) {
-		if (trace->found_issue || trace->found_completion)
-			hash_queued_io(trace->io);
+		if (io->sector = 0)
+			return;
+		if (trace->found_issue || trace->found_completion) {
+			pio = hash_queued_io(trace->io);
+			/*
+			 * When there are no ISSUE events count depth and
+			 * latency at least from queue events
+			 */
+			if (pio && !trace->found_issue) {
+				pio->dispatch_time = io->time;
+				goto account_io;
+			}
+		}
 		return;
 	}
 	if (action = __BLK_TA_REQUEUE) {
@@ -1118,6 +1129,7 @@ void add_pending_io(struct trace *trace, struct graph_line_data *gld)
 		free(pio);
 	}
 
+account_io:
 	ios_in_flight++;
 
 	seconds = SECONDS(io->time);
iowatcher/main.c +38 -21

149 lines not on this page · raw message

iowatcher/plot.c +24 -4
index 012d4f9..372406b 100644
@@ -759,6 +759,29 @@ void scale_line_graph_time(u64 *max, char **units)
 	*max /= div;
 }
 
+static int rolling_span(struct graph_line_data *gld)
+{
+	if (rolling_avg_secs)
+		return rolling_avg_secs;
+	return (gld->stop_seconds - gld->min_seconds) / 25;
+}
+
+
+double line_graph_roll_avg_max(struct graph_line_data *gld)
+{
+	unsigned int i;
+	int rolling;
+	double avg, max = 0;
+
+	rolling = rolling_span(gld);
+	for (i = gld->min_seconds; i < gld->stop_seconds; i++) {
+		avg = rolling_avg(gld->data, i, rolling);
+		if (avg > max)
+			max = avg;
+	}
+	return max;
+}
+
 int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color, int thresh1, int thresh2)
 {
 	unsigned int i;
@@ -776,10 +799,8 @@ int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color,
 
 	if (thresh1 && thresh2)
 		rolling = 0;
-	else if (rolling_avg_secs)
-		rolling = rolling_avg_secs;
 	else
-		rolling = (gld->stop_seconds - gld->min_seconds) / 25;
+		rolling = rolling_span(gld);
 
 	for (i = gld->min_seconds; i < gld->stop_seconds; i++) {
 		avg = rolling_avg(gld->data, i, rolling);
@@ -795,7 +816,6 @@ int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color,
 
 		x = (double)(i - gld->min_seconds) / xscale;
 		if (!thresh1 && !thresh2) {
-
 			if (!printed_header) {
 				write_check(fd, start, strlen(start));
 				printed_header = 1;
iowatcher/plot.h +1 -0
index 7e87b1d..d65bbcf 100644
@@ -137,6 +137,7 @@ char *pick_fio_color(void);
 char *pick_cpu_color(void);
 void reset_cpu_color(void);
 int svg_io_graph(struct plot *plot, struct graph_dot_data *gdd);
+double line_graph_roll_avg_max(struct graph_line_data *gld);
 int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color, int thresh1, int thresh2);
 struct graph_line_data *alloc_line_data(unsigned int min_seconds, unsigned int max_seconds, unsigned int stop_seconds);
 struct graph_dot_data *alloc_dot_data(unsigned int min_seconds, unsigned int max_seconds, u64 min_offset, u64 max_offset, unsigned int stop_seconds, char *color, char *label);
#14 lore raw
In reply to Jens Axboe

The following changes since commit 7644909627859a9d9d837df8b2ecf21a169f0ff0:

Fixup graph name in help text (2016-05-05 09:20:18 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 86596c7579c6e374e6e24c2b14398b0808a93f18:

blktrace: remove -k from manpage synopsis (2016-05-19 15:57:22 -0600)

----------------------------------------------------------------
Eric Sandeen (1):
blktrace: remove -k from manpage synopsis

 doc/blktrace.8 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

doc/blktrace.8 +1 -1
index 68f5e15..820b03a 100644
@@ -6,7 +6,7 @@ blktrace \- generate traces of the i/o traffic on block devices
 
 
 .SH SYNOPSIS
-.B blktrace \-d \fIdev\fR [ \-r \fIdebugfs_path\fR ] [ \-o \fIoutput\fR ] [\-k ] [ \-w \fItime\fR ] [ \-a \fIaction\fR ] [ \-A \fIaction_mask\fR ] [ \-v ]
+.B blktrace \-d \fIdev\fR [ \-r \fIdebugfs_path\fR ] [ \-o \fIoutput\fR ] [ \-w \fItime\fR ] [ \-a \fIaction\fR ] [ \-A \fIaction_mask\fR ] [ \-v ]
 .br
 
 
#15 lore raw
In reply to Jens Axboe

The following changes since commit 86596c7579c6e374e6e24c2b14398b0808a93f18:

blktrace: remove -k from manpage synopsis (2016-05-19 15:57:22 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to d1ab783430f5a832e973ed9a293da146c04c6702:

iowatcher: link with -lrt (2016-08-23 08:45:45 -0600)

----------------------------------------------------------------
Thomas Petazzoni (1):
iowatcher: link with -lrt

 iowatcher/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

iowatcher/Makefile +1 -1
index 3551ea0..e013556 100644
@@ -19,7 +19,7 @@ all: $(ALL)
 	$(CC) -o $*.o -c $(ALL_CFLAGS) $<
 
 iowatcher: blkparse.o plot.o main.o tracers.o mpstat.o fio.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) -lm
+	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) -lm -lrt
 
 depend:
 	@$(CC) -MM $(ALL_CFLAGS) *.c 1> .depend
#16 lore raw
In reply to Jens Axboe

The following changes since commit d1ab783430f5a832e973ed9a293da146c04c6702:

iowatcher: link with -lrt (2016-08-23 08:45:45 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 8772bc4fb049bdd879de5952d6f291a34112fae0:

blktrace: Create empty output files for non-existent cpus (2017-01-26 10:06:05 -0700)

----------------------------------------------------------------
Jan Kara (3):
blktrace: Add support for sparse CPU numbers
blktrace: Reorganize creation of output file name
blktrace: Create empty output files for non-existent cpus

 blktrace.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 156 insertions(+), 35 deletions(-)

---

Diff of recent changes:

blktrace.c +156 -35
index b445524..e8f2f87 100644
@@ -274,7 +274,9 @@ static char blktrace_version[] = "2.0.0";
 int data_is_native = -1;
 
 static int ndevs;
+static int max_cpus;
 static int ncpus;
+static cpu_set_t *online_cpus;
 static int pagesize;
 static int act_mask = ~0U;
 static int kill_running_trace;
@@ -623,8 +625,9 @@ static int lock_on_cpu(int cpu)
 {
 	cpu_set_t * cpu_mask;
 	size_t size;
-	cpu_mask = CPU_ALLOC(ncpus);
-	size = CPU_ALLOC_SIZE(ncpus);
+
+	cpu_mask = CPU_ALLOC(max_cpus);
+	size = CPU_ALLOC_SIZE(max_cpus);
 
 	CPU_ZERO_S(size, cpu_mask);
 	CPU_SET_S(cpu, size, cpu_mask);
@@ -882,7 +885,7 @@ static int net_send_header(int fd, int cpu, char *buts_name, int len)
 	strncpy(hdr.buts_name, buts_name, sizeof(hdr.buts_name));
 	hdr.buts_name[sizeof(hdr.buts_name) - 1] = '\0';
 	hdr.cpu = cpu;
-	hdr.max_cpus = ncpus;
+	hdr.max_cpus = max_cpus;
 	hdr.len = len;
 	hdr.cl_id = getpid();
 	hdr.buf_size = buf_size;
@@ -1026,9 +1029,12 @@ static int net_setup_client(void)
 static int open_client_connections(void)
 {
 	int cpu;
+	size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
 
 	cl_fds = calloc(ncpus, sizeof(*cl_fds));
-	for (cpu = 0; cpu < ncpus; cpu++) {
+	for (cpu = 0; cpu < max_cpus; cpu++) {
+		if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+			continue;
 		cl_fds[cpu] = net_setup_client();
 		if (cl_fds[cpu] < 0)
 			goto err;
@@ -1046,8 +1052,11 @@ static void close_client_connections(void)
 {
 	if (cl_fds) {
 		int cpu, *fdp;
+		size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
 
-		for (cpu = 0, fdp = cl_fds; cpu < ncpus; cpu++, fdp++) {
+		for (cpu = 0, fdp = cl_fds; cpu < max_cpus; cpu++, fdp++) {
+			if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+				continue;
 			if (*fdp >= 0) {
 				net_send_drops(*fdp);
 				net_close_connection(fdp);
@@ -1071,7 +1080,7 @@ static void setup_buts(void)
 		buts.act_mask = act_mask;
 
 		if (ioctl(dpp->fd, BLKTRACESETUP, &buts) >= 0) {
-			dpp->ncpus = ncpus;
+			dpp->ncpus = max_cpus;
 			dpp->buts_name = strdup(buts.name);
 			if (dpp->stats)
 				free(dpp->stats);
@@ -1155,7 +1164,7 @@ static void free_tracer_heads(struct devpath *dpp)
 	int cpu;
 	struct tracer_devpath_head *hd;
 
-	for (cpu = 0, hd = dpp->heads; cpu < ncpus; cpu++, hd++) {
+	for (cpu = 0, hd = dpp->heads; cpu < max_cpus; cpu++, hd++) {
 		if (hd->prev)
 			free(hd->prev);
 
@@ -1177,8 +1186,8 @@ static int setup_tracer_devpaths(void)
 		struct tracer_devpath_head *hd;
 		struct devpath *dpp = list_entry(p, struct devpath, head);
 
-		dpp->heads = calloc(ncpus, sizeof(struct tracer_devpath_head));
-		for (cpu = 0, hd = dpp->heads; cpu < ncpus; cpu++, hd++) {
+		dpp->heads = calloc(max_cpus, sizeof(struct tracer_devpath_head));
+		for (cpu = 0, hd = dpp->heads; cpu < max_cpus; cpu++, hd++) {
 			INIT_LIST_HEAD(&hd->head);
 			pthread_mutex_init(&hd->mutex, NULL);
 			hd->prev = NULL;
@@ -1426,7 +1435,7 @@ static void __process_trace_bufs(void)
 		struct devpath *dpp = list_entry(p, struct devpath, head);
 		struct tracer_devpath_head *hd = dpp->heads;
 
-		for (cpu = 0; cpu < ncpus; cpu++, hd++) {
+		for (cpu = 0; cpu < max_cpus; cpu++, hd++) {
 			pthread_mutex_lock(&hd->mutex);
 			if (list_empty(&hd->head)) {
 				pthread_mutex_unlock(&hd->mutex);
@@ -1493,30 +1502,25 @@ static inline int net_sendfile_data(struct tracer *tp, struct io_info *iop)
 	return net_sendfile(iop);
 }
 
-static int fill_ofname(struct io_info *iop, int cpu)
+static int fill_ofname(char *dst, int dstlen, char *subdir, char *buts_name,
+		       int cpu)
 {
 	int len;
 	struct stat sb;
-	char *dst = iop->ofn;
 
 	if (output_dir)
-		len = snprintf(iop->ofn, sizeof(iop->ofn), "%s/", output_dir);
+		len = snprintf(dst, dstlen, "%s/", output_dir);
 	else
-		len = snprintf(iop->ofn, sizeof(iop->ofn), "./");
+		len = snprintf(dst, dstlen, "./");
 
-	if (net_mode = Net_server) {
-		struct cl_conn *nc = iop->nc;
-
-		len += sprintf(dst + len, "%s-", nc->ch->hostname);
-		len += strftime(dst + len, 64, "%F-%T/",
-				gmtime(&iop->dpp->cl_connect_time));
-	}
+	if (subdir)
+		len += snprintf(dst + len, dstlen - len, "%s", subdir);
 
-	if (stat(iop->ofn, &sb) < 0) {
+	if (stat(dst, &sb) < 0) {
 		if (errno != ENOENT) {
 			fprintf(stderr,
 				"Destination dir %s stat failed: %d/%s\n",
-				iop->ofn, errno, strerror(errno));
+				dst, errno, strerror(errno));
 			return 1;
 		}
 		/*
@@ -1524,20 +1528,20 @@ static int fill_ofname(struct io_info *iop, int cpu)
 		 * trying to create the directory at once.  It's harmless
 		 * to let them try, so just detect the problem and move on.
 		 */
-		if (mkdir(iop->ofn, 0755) < 0 && errno != EEXIST) {
+		if (mkdir(dst, 0755) < 0 && errno != EEXIST) {
 			fprintf(stderr,
 				"Destination dir %s can't be made: %d/%s\n",
-				iop->ofn, errno, strerror(errno));
+				dst, errno, strerror(errno));
 			return 1;
 		}
 	}
 
 	if (output_name)
-		snprintf(iop->ofn + len, sizeof(iop->ofn), "%s.blktrace.%d",
+		snprintf(dst + len, dstlen - len, "%s.blktrace.%d",
 			 output_name, cpu);
 	else
-		snprintf(iop->ofn + len, sizeof(iop->ofn), "%s.blktrace.%d",
-			 iop->dpp->buts_name, cpu);
+		snprintf(dst + len, dstlen - len, "%s.blktrace.%d",
+			 buts_name, cpu);
 
 	return 0;
 }
@@ -1558,8 +1562,23 @@ static int set_vbuf(struct io_info *iop, int mode, size_t size)
 
 static int iop_open(struct io_info *iop, int cpu)
 {
+	char hostdir[MAXPATHLEN + 64];
+
 	iop->ofd = -1;
-	if (fill_ofname(iop, cpu))
+	if (net_mode = Net_server) {
+		struct cl_conn *nc = iop->nc;
+		int len;
+
+		len = snprintf(hostdir, sizeof(hostdir), "%s-",
+			       nc->ch->hostname);
+		len += strftime(hostdir + len, sizeof(hostdir) - len, "%F-%T/",
+				gmtime(&iop->dpp->cl_connect_time));
+	} else {
+		hostdir[0] = 0;
+	}
+
+	if (fill_ofname(iop->ofn, sizeof(iop->ofn), hostdir,
+			iop->dpp->buts_name, cpu))
 		return 1;
 
 	iop->ofp = my_fopen(iop->ofn, "w+");
@@ -1874,16 +1893,49 @@ static int start_tracer(int cpu)
 	return 0;
 }
 
+static int create_output_files(int cpu)
+{
+	char fname[MAXPATHLEN + 64];
+	struct list_head *p;
+	FILE *f;
+
+	__list_for_each(p, &devpaths) {
+		struct devpath *dpp = list_entry(p, struct devpath, head);
+
+		if (fill_ofname(fname, sizeof(fname), NULL, dpp->buts_name,
+				cpu))
+			return 1;
+		f = my_fopen(fname, "w+");
+		if (!f)
+			return 1;
+		fclose(f);
+	}
+	return 0;
+}
+
 static void start_tracers(void)
 {
-	int cpu;
+	int cpu, started = 0;
 	struct list_head *p;
+	size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
 
-	for (cpu = 0; cpu < ncpus; cpu++)
+	for (cpu = 0; cpu < max_cpus; cpu++) {
+		if (!CPU_ISSET_S(cpu, alloc_size, online_cpus)) {
+			/*
+			 * Create fake empty output files so that other tools
+			 * like blkparse don't have to bother with sparse CPU
+			 * number space.
+			 */
+			if (create_output_files(cpu))
+				break;
+			continue;
+		}
 		if (start_tracer(cpu))
 			break;
+		started++;
+	}
 
-	wait_tracers_ready(cpu);
+	wait_tracers_ready(started);
 
 	__list_for_each(p, &tracers) {
 		struct tracer *tp = list_entry(p, struct tracer, head);
@@ -2657,15 +2709,83 @@ static int run_tracers(void)
 	return 0;
 }
 
+static cpu_set_t *get_online_cpus(void)
+{
+	FILE *cpus;
+	cpu_set_t *set;
+	size_t alloc_size;
+	int cpuid, prevcpuid = -1;
+	char nextch;
+	int n, ncpu, curcpu = 0;
+	int *cpu_nums;
+
+	ncpu = sysconf(_SC_NPROCESSORS_CONF);
+	if (ncpu < 0)
+		return NULL;
+
+	cpu_nums = malloc(sizeof(int)*ncpu);
+	if (!cpu_nums) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	/*
+	 * There is no way to easily get maximum CPU number. So we have to
+	 * parse the file first to find it out and then create appropriate
+	 * cpuset
+	 */
+	cpus = my_fopen("/sys/devices/system/cpu/online", "r");
+	for (;;) {
+		n = fscanf(cpus, "%d%c", &cpuid, &nextch);
+		if (n <= 0)
+			break;
+		if (n = 2 && nextch = '-') {
+			prevcpuid = cpuid;
+			continue;
+		}
+		if (prevcpuid = -1)
+			prevcpuid = cpuid;
+		while (prevcpuid <= cpuid) {
+			/* More CPUs listed than configured? */
+			if (curcpu >= ncpu) {
+				errno = EINVAL;
+				return NULL;
+			}
+			cpu_nums[curcpu++] = prevcpuid++;
+		}
+		prevcpuid = -1;
+	}
+	fclose(cpus);
+
+	ncpu = curcpu;
+	max_cpus = cpu_nums[ncpu - 1] + 1;
+
+	/* Now that we have maximum cpu number, create a cpuset */
+	set = CPU_ALLOC(max_cpus);
+	if (!set) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	alloc_size = CPU_ALLOC_SIZE(max_cpus);
+	CPU_ZERO_S(alloc_size, set);
+
+	for (curcpu = 0; curcpu < ncpu; curcpu++)
+		CPU_SET_S(cpu_nums[curcpu], alloc_size, set);
+
+	free(cpu_nums);
+
+	return set;
+}
+
 int main(int argc, char *argv[])
 {
 	int ret = 0;
 
 	setlocale(LC_NUMERIC, "en_US");
 	pagesize = getpagesize();
-	ncpus = sysconf(_SC_NPROCESSORS_ONLN);
-	if (ncpus < 0) {
-		fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed %d/%s\n",
+	online_cpus = get_online_cpus();
+	if (!online_cpus) {
+		fprintf(stderr, "cannot get online cpus %d/%s\n",
 			errno, strerror(errno));
 		ret = 1;
 		goto out;
@@ -2674,6 +2794,7 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 
+	ncpus = CPU_COUNT_S(CPU_ALLOC_SIZE(max_cpus), online_cpus);
 	if (ndevs > 1 && output_name && strcmp(output_name, "-") != 0) {
 		fprintf(stderr, "-o not supported with multiple devices\n");
 		ret = 1;
#17 lore raw
In reply to Jens Axboe

The following changes since commit 8772bc4fb049bdd879de5952d6f291a34112fae0:

blktrace: Create empty output files for non-existent cpus (2017-01-26 10:06:05 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to cca113f2fe0759b91fd6a0e10fdcda2c28f18a7e:

Blktrace 1.2.0 (2017-11-04 22:13:06 -0600)

----------------------------------------------------------------
Jens Axboe (2):
blktrace: abort if device ioctl setup fails
Blktrace 1.2.0

 blkparse.c |  2 +-
 blktrace.c | 12 +++++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

---

Diff of recent changes:

blkparse.c +1 -1
index ab5edc2..227cc44 100644
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.1.0";
+static char blkparse_version[] = "1.2.0";
 
 struct skip_info {
 	unsigned long start, end;
blktrace.c +9 -3
index e8f2f87..e048f68 100644
@@ -1066,9 +1066,10 @@ static void close_client_connections(void)
 	}
 }
 
-static void setup_buts(void)
+static int setup_buts(void)
 {
 	struct list_head *p;
+	int ret = 0;
 
 	__list_for_each(p, &devpaths) {
 		struct blk_user_trace_setup buts;
@@ -1086,10 +1087,14 @@ static void setup_buts(void)
 				free(dpp->stats);
 			dpp->stats = calloc(dpp->ncpus, sizeof(*dpp->stats));
 			memset(dpp->stats, 0, dpp->ncpus * sizeof(*dpp->stats));
-		} else
+		} else {
 			fprintf(stderr, "BLKTRACESETUP(2) %s failed: %d/%s\n",
 				dpp->path, errno, strerror(errno));
+			ret++;
+		}
 	}
+
+	return ret;
 }
 
 static void start_buts(void)
@@ -2676,7 +2681,8 @@ static int run_tracers(void)
 	if (net_mode = Net_client)
 		printf("blktrace: connecting to %s\n", hostname);
 
-	setup_buts();
+	if (setup_buts())
+		return 1;
 
 	if (use_tracer_devpaths()) {
 		if (setup_tracer_devpaths())
#18 lore raw
In reply to Jens Axboe

The following changes since commit cca113f2fe0759b91fd6a0e10fdcda2c28f18a7e:

Blktrace 1.2.0 (2017-11-04 22:13:06 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 07d76e12aa46fa0bad4b736d581ec5aca62264f7:

btt/devs: silence warning on sprintf overflow (2017-11-05 08:54:41 -0700)

----------------------------------------------------------------
Jens Axboe (2):
jhash: fix annoying gcc fall through warnings btt/devs: silence warning on sprintf overflow

 btt/devs.c |  2 +-
 jhash.h    | 34 ++++++++++++++++------------------
 2 files changed, 17 insertions(+), 19 deletions(-)

---

Diff of recent changes:

btt/devs.c +1 -1
index ccaae87..12ce2ca 100644
@@ -108,7 +108,7 @@ void dip_exit(void)
 static inline FILE *open_pit(struct d_info *dip)
 {
 	FILE *fp;
-	char str[256];
+	char str[272];
 
 	sprintf(str, "%s_pit.dat", dip->dip_name);
 	if ((fp = my_fopen(str, "w")) = NULL)
jhash.h +16 -18
index 4cebd23..a4d3106 100644
@@ -73,22 +73,21 @@ static inline u32 jhash(const void *key, u32 length, u32 initval)
 		k += 12;
 	}
 
-	/* last block: affect all 32 bits of (c) */
-	/* all the case statements fall through */
+	/* Last block: affect all 32 bits of (c) */
 	switch (length) {
-	case 12: c += (u32)k[11]<<24;
-	case 11: c += (u32)k[10]<<16;
-	case 10: c += (u32)k[9]<<8;
-	case 9 : c += k[8];
-	case 8 : b += (u32)k[7]<<24;
-	case 7 : b += (u32)k[6]<<16;
-	case 6 : b += (u32)k[5]<<8;
-	case 5 : b += k[4];
-	case 4 : a += (u32)k[3]<<24;
-	case 3 : a += (u32)k[2]<<16;
-	case 2 : a += (u32)k[1]<<8;
-	case 1 : a += k[0];
-		__jhash_final(a, b, c);
+	case 12: c += (u32)k[11]<<24;	/* fall through */
+	case 11: c += (u32)k[10]<<16;	/* fall through */
+	case 10: c += (u32)k[9]<<8;	/* fall through */
+	case 9:  c += k[8];		/* fall through */
+	case 8:  b += (u32)k[7]<<24;	/* fall through */
+	case 7:  b += (u32)k[6]<<16;	/* fall through */
+	case 6:  b += (u32)k[5]<<8;	/* fall through */
+	case 5:  b += k[4];		/* fall through */
+	case 4:  a += (u32)k[3]<<24;	/* fall through */
+	case 3:  a += (u32)k[2]<<16;	/* fall through */
+	case 2:  a += (u32)k[1]<<8;	/* fall through */
+	case 1:  a += k[0];
+		 __jhash_final(a, b, c);
 	case 0 :
 		break;
 	}
@@ -117,10 +116,9 @@ static inline u32 jhash2(u32 *k, u32 length, u32 initval)
 	}
 
 	/* handle the last 3 u32's */
-	/* all the case statements fall through */ 
 	switch (length) {
-	case 3: c += k[2];
-	case 2: b += k[1];
+	case 3: c += k[2];	/* fall through */
+	case 2: b += k[1];	/* fall through */
 	case 1: a += k[0];
 		__jhash_final(a, b, c);
 	case 0:     /* case 0: nothing left to add */
#19 lore raw
In reply to Jens Axboe

The following changes since commit 07d76e12aa46fa0bad4b736d581ec5aca62264f7:

btt/devs: silence warning on sprintf overflow (2017-11-05 08:54:41 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 8fc451c6b0b9a7db7c376ea6865c35321e561f00:

btt: Fix overlapping IO stats. (2017-11-07 11:25:38 -0700)

----------------------------------------------------------------
Gwendal Grignou (1):
btt: Fix overlapping IO stats.

 btt/dip_rb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

---

Diff of recent changes:

btt/dip_rb.c +2 -2
index 2aa7ffc..6efef6c 100644
@@ -57,7 +57,7 @@ struct io *rb_find_sec(struct rb_root *root, __u64 sec)
 		__iop = rb_entry(n, struct io, rb_node);
 		if (sec < BIT_START(__iop))
 			n = n->rb_left;
-		else if (sec >= BIT_END(__iop))
+		else if (sec > BIT_START(__iop))
 			n = n->rb_right;
 		else
 			return __iop;
@@ -82,7 +82,7 @@ void rb_foreach(struct rb_node *n, struct io *iop,
 		}
 		if (iop_s < this_s)
 			rb_foreach(n->rb_left, iop, fnc, head);
-		if (this_e < iop_e)
+		if ((this_e < iop_e) || (this_s < iop_s))
 			rb_foreach(n->rb_right, iop, fnc, head);
 	}
 }
#20 lore raw
In reply to Jens Axboe

The following changes since commit 8fc451c6b0b9a7db7c376ea6865c35321e561f00:

btt: Fix overlapping IO stats. (2017-11-07 11:25:38 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 519fd9a5d08d85f3d9cb4192d624fe8351e40232:

fix parallel build failures (2018-01-23 15:59:13 -0700)

----------------------------------------------------------------
Robin H. Johnson (2):
respect LDFLAGS when linking programs
fix parallel build failures

 Makefile           | 34 +++++++++++++++-------------------
 btreplay/Makefile  |  4 ++--
 btt/Makefile       |  2 +-
 iowatcher/Makefile |  2 +-
 4 files changed, 19 insertions(+), 23 deletions(-)

---

Diff of recent changes:

Makefile +15 -19
index fdbded0..5917814 100644
@@ -4,41 +4,37 @@ ALL_CFLAGS = $(CFLAGS) -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITSd
 PROGS	= blkparse blktrace verify_blkparse blkrawverify blkiomon
 LIBS	= -lpthread
 SCRIPTS	= btrace
+SUBDIRS = btreplay btt iowatcher
 
-ALL = $(PROGS) $(SCRIPTS) btt/btt btreplay/btrecord btreplay/btreplay \
+ALL = $(PROGS) $(SCRIPTS)
+INSTALL_ALL = $(ALL) btt/btt btreplay/btrecord btreplay/btreplay \
       btt/bno_plot.py iowatcher/iowatcher
 
-all: $(ALL)
+all: $(ALL) $(SUBDIRS)
 
-btt/btt:
-	$(MAKE) -C btt
-
-iowatcher/iowatcher:
-	$(MAKE) -C iowatcher
-
-btreplay/btrecord:
-	$(MAKE) -C btreplay
-
-btreplay/btreplay:
-	$(MAKE) -C btreplay
+# We always descend into subdirs because they contain their own dependency
+# information which we don't track in this top level Makefile.
+$(SUBDIRS):
+	$(MAKE) -C $@
+.PHONY: $(SUBDIRS)
 
 %.o: %.c
 	$(CC) -o $*.o -c $(ALL_CFLAGS) $<
 
 blkparse: blkparse.o blkparse_fmt.o rbtree.o act_mask.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^)
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^)
 
 blktrace: blktrace.o act_mask.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
 
 verify_blkparse: verify_blkparse.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^)
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^)
 
 blkrawverify: blkrawverify.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^)
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^)
 
 blkiomon: blkiomon.o rbtree.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) -lrt
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS) -lrt
 
 $(PROGS): | depend
 
@@ -85,7 +81,7 @@ install: all
 	$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
 	$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
 	$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
-	$(INSTALL) -m 755 $(ALL) $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 $(INSTALL_ALL) $(DESTDIR)$(bindir)
 	$(INSTALL) -m 644 doc/*.1 $(DESTDIR)$(mandir)/man1
 	$(INSTALL) -m 644 doc/*.8 $(DESTDIR)$(mandir)/man8
 
btreplay/Makefile +2 -2
index 2998182..f574a29 100644
@@ -32,10 +32,10 @@ clean: docsclean
 	$(CC) $(CFLAGS) -c -o $*.o $<
 
 btrecord: btrecord.o
-	$(CC) $(CFLAGS) -o $@ $(filter %.o,$^)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^)
 
 btreplay: btreplay.o
-	$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
 
 depend:
 	@$(CC) -MM $(CFLAGS) *.c 1> .depend
btt/Makefile +1 -1
index df7a3de..3207557 100644
@@ -38,7 +38,7 @@ clean: docsclean
 	$(CC) $(CFLAGS) -c -o $*.o $<
 
 btt: $(OBJS)
-	$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
 
 ifneq ($(wildcard .depend),)
 include .depend
iowatcher/Makefile +1 -1
index e013556..a224a08 100644
@@ -19,7 +19,7 @@ all: $(ALL)
 	$(CC) -o $*.o -c $(ALL_CFLAGS) $<
 
 iowatcher: blkparse.o plot.o main.o tracers.o mpstat.o fio.o
-	$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) -lm -lrt
+	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) -lm -lrt
 
 depend:
 	@$(CC) -MM $(ALL_CFLAGS) *.c 1> .depend
#21 lore raw
In reply to Jens Axboe

The following changes since commit 519fd9a5d08d85f3d9cb4192d624fe8351e40232:

fix parallel build failures (2018-01-23 15:59:13 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to e63098f39398bde67be9b64a49deece1c60614df:

blktrace: don't stop tracer if not setup trace successfully (2018-01-24 08:40:52 -0700)

----------------------------------------------------------------
weiping zhang (1):
blktrace: don't stop tracer if not setup trace successfully

 blktrace.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

---

Diff of recent changes:

blktrace.c +4 -1
index e048f68..d0d271f 100644
@@ -112,6 +112,7 @@ struct devpath {
 	struct cl_host *ch;
 	u32 cl_id;
 	time_t cl_connect_time;
+	int setup_done;	/* ioctl BLKTRACESETUP done */
 	struct io_info *ios;
 };
 
@@ -1083,6 +1084,7 @@ static int setup_buts(void)
 		if (ioctl(dpp->fd, BLKTRACESETUP, &buts) >= 0) {
 			dpp->ncpus = max_cpus;
 			dpp->buts_name = strdup(buts.name);
+			dpp->setup_done = 1;
 			if (dpp->stats)
 				free(dpp->stats);
 			dpp->stats = calloc(dpp->ncpus, sizeof(*dpp->stats));
@@ -1285,7 +1287,8 @@ static void rel_devpaths(void)
 		struct devpath *dpp = list_entry(p, struct devpath, head);
 
 		list_del(&dpp->head);
-		__stop_trace(dpp->fd);
+		if (dpp->setup_done)
+			__stop_trace(dpp->fd);
 		close(dpp->fd);
 
 		if (dpp->heads)
#22 lore raw
In reply to Jens Axboe

The following changes since commit e63098f39398bde67be9b64a49deece1c60614df:

blktrace: don't stop tracer if not setup trace successfully (2018-01-24 08:40:52 -0700)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 93d9e5b5082258f3570dbc56202276284575fc11:

blkparse: add documetation for 'R' requeue request (2018-04-09 08:36:43 -0600)

----------------------------------------------------------------
Weiping Zhang (2):
blkparse: remove duplicated entry for flag M
blkparse: add documetation for 'R' requeue request

 doc/blkparse.1 | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

---

Diff of recent changes:

doc/blkparse.1 +4 -4
index be9b34b..cb21fea 100644
@@ -243,10 +243,6 @@ Same as the back merge, except this i/o ends where a previously inserted
 requests starts.
 
 .HP 4
-\fBM --front or back merge\fR
-One of the above
-
-.HP 4
 \fBM -- front or back merge\fR
 One of the above.
 
@@ -289,6 +285,10 @@ this and will clone lots of i/o.
 For stacked devices, incoming i/o is remapped to device below it in the i/o
 stack. The remap action details what exactly is being remapped to what.
 
+.HP 4
+\fBR -- requeue\fR
+Put a request back on queue.
+
 
 
 
#23 lore raw
In reply to Jens Axboe

The following changes since commit 93d9e5b5082258f3570dbc56202276284575fc11:

blkparse: add documetation for 'R' requeue request (2018-04-09 08:36:43 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to d61ff409cb4dda31386373d706ea0cfb1aaac5b7:

btt: make device/devno use PATH_MAX to avoid overflow (2018-05-02 10:24:17 -0600)

----------------------------------------------------------------
Jens Axboe (1):
btt: make device/devno use PATH_MAX to avoid overflow

 btt/devmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

btt/devmap.c +1 -1
index 0553a9e..5fc1cb2 100644
@@ -23,7 +23,7 @@
 
 struct devmap {
 	struct list_head head;
-	char device[32], devno[32];
+	char device[PATH_MAX], devno[PATH_MAX];
 };
 
 LIST_HEAD(all_devmaps);
#24 lore raw
In reply to Jens Axboe

The following changes since commit d61ff409cb4dda31386373d706ea0cfb1aaac5b7:

btt: make device/devno use PATH_MAX to avoid overflow (2018-05-02 10:24:17 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 70d5ca2d5f3d6b97c11c641b7e0c5836983219a0:

make btt scripts python3-ready (2018-05-16 13:09:58 -0600)

----------------------------------------------------------------
Eric Sandeen (1):
make btt scripts python3-ready

 btt/bno_plot.py | 28 +++++++++++++++-------------
 btt/btt_plot.py | 22 +++++++++++++---------
 2 files changed, 28 insertions(+), 22 deletions(-)

---

Diff of recent changes:

btt/bno_plot.py +15 -13
index aa92480..f05cfdc 100644
@@ -38,6 +38,8 @@ automatically push the keys under the graph.
 To exit the plotter, enter 'quit' or ^D at the 'gnuplot> ' prompt.
 """
 
+from __future__ import absolute_import
+from __future__ import print_function
 import getopt, glob, os, sys, tempfile
 
 verbose	= 0
@@ -60,14 +62,14 @@ def parse_args(in_args):
 
 	try:
 		(opts, args) = getopt.getopt(in_args, s_opts, l_opts)
-	except getopt.error, msg:
-		print >>sys.stderr, msg
-		print >>sys.stderr, __doc__
+	except getopt.error as msg:
+		print(msg, file=sys.stderr)
+		print(__doc__, file=sys.stderr)
 		sys.exit(1)
 
 	for (o, a) in opts:
 		if o in ('-h', '--help'):
-			print __doc__
+			print(__doc__)
 			sys.exit(0)
 		elif o in ('-v', '--verbose'):
 			verbose += 1
@@ -84,10 +86,10 @@ if __name__ = '__main__':
 	(bnos, keys_below) = parse_args(sys.argv[1:])
 
 	if verbose:
-		print 'Using files:',
-		for bno in bnos: print bno,
-		if keys_below:	print '\nKeys are to be placed below graph'
-		else:		print ''
+		print('Using files:', end=' ')
+		for bno in bnos: print(bno, end=' ')
+		if keys_below:	print('\nKeys are to be placed below graph')
+		else:		print('')
 
 	tmpdir = tempfile.mktemp()
 	os.mkdir(tmpdir)
@@ -99,7 +101,7 @@ if __name__ = '__main__':
 		fo = open(t, 'w')
 		for line in open(f, 'r'):
 			fld = line.split(None)
-			print >>fo, fld[0], fld[1], int(fld[2])-int(fld[1])
+			print(fld[0], fld[1], int(fld[2])-int(fld[1]), file=fo)
 		fo.close()
 
 		t = t[t.rfind('/')+1:]
@@ -107,16 +109,16 @@ if __name__ = '__main__':
 		else:                plot_cmd = "%s,'%s'" % (plot_cmd, t)
 
 	fo = open('%s/plot.cmds' % tmpdir, 'w')
-	print >>fo, cmds
-	if len(bnos) > 10 or keys_below: print >>fo, 'set key below'
-	print >>fo, plot_cmd
+	print(cmds, file=fo)
+	if len(bnos) > 10 or keys_below: print('set key below', file=fo)
+	print(plot_cmd, file=fo)
 	fo.close()
 
 	pid = os.fork()
 	if pid = 0:
 		cmd = 'gnuplot %s/plot.cmds -' % tmpdir
 
-		if verbose: print 'Executing %s' % cmd
+		if verbose: print('Executing %s' % cmd)
 
 		os.chdir(tmpdir)
 		os.system(cmd)
btt/btt_plot.py +13 -9
index b81dad5..76fcca8 100755
@@ -55,6 +55,10 @@ Arguments:
   but the -o (--output) and -T (--title) options will be ignored.
 """
 
+from __future__ import absolute_import
+from __future__ import print_function
+import six
+from six.moves import range
 __author__ = 'Alan D. Brunelle <[email protected]>'
 
 #------------------------------------------------------------------------------
@@ -82,7 +86,7 @@ get_base 	= lambda file: file[file.find('_')+1:file.rfind('_')]
 def fatal(msg):
 	"""Generate fatal error message and exit"""
 
-	print >>sys.stderr, 'FATAL: %s' % msg
+	print('FATAL: %s' % msg, file=sys.stderr)
 	sys.exit(1)
 
 #------------------------------------------------------------------------------
@@ -163,7 +167,7 @@ def get_data(files):
 		if not os.path.exists(file):
 			fatal('%s not found' % file)
 		elif verbose:
-			print 'Processing %s' % file
+			print('Processing %s' % file)
 
 		xs = []
 		ys = []
@@ -214,8 +218,8 @@ def parse_args(args):
 
 	try:
 		(opts, args) = getopt.getopt(args[1:], s_opts, l_opts)
-	except getopt.error, msg:
-		print >>sys.stderr, msg
+	except getopt.error as msg:
+		print(msg, file=sys.stderr)
 		fatal(__doc__)
 
 	for (o, a) in opts:
@@ -293,15 +297,15 @@ def generate_output(type, db):
 	def color(idx, style):
 		"""Returns a color/symbol type based upon the index passed."""
 
-                colors = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k' ]
+		colors = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k' ]
 		l_styles = [ '-', ':', '--', '-.' ]
 		m_styles = [ 'o', '+', '.', ',', 's', 'v', 'x', '<', '>' ]
 
 		color = colors[idx % len(colors)]
 		if style = 'line':
-			style = l_styles[(idx / len(l_styles)) % len(l_styles)]
+			style = l_styles[int((idx / len(l_styles)) % len(l_styles))]
 		elif style = 'marker':
-			style = m_styles[(idx / len(m_styles)) % len(m_styles)]
+			style = m_styles[int((idx / len(m_styles)) % len(m_styles))]
 
 		return '%s%s' % (color, style)
 
@@ -314,7 +318,7 @@ def generate_output(type, db):
 		ofile = '%s.png' % type
 
 	if verbose:
-		print 'Generating plot into %s' % ofile
+		print('Generating plot into %s' % ofile)
 
 	fig = plt.figure(figsize=plot_size)
 	ax = fig.add_subplot(111)
@@ -329,7 +333,7 @@ def generate_output(type, db):
 		legends = None
 
 	keys = []
-	for file in db.iterkeys():
+	for file in six.iterkeys(db):
 		if not file in ['min_x', 'max_x', 'min_y', 'max_y']:
 			keys.append(file)
 
#25 lore raw
In reply to Jens Axboe

The following changes since commit 70d5ca2d5f3d6b97c11c641b7e0c5836983219a0:

make btt scripts python3-ready (2018-05-16 13:09:58 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to f011d96f260a2be5dcc2ad9f4d1bf2d591946723:

iowatcher: don't add Q events to the io hash (2018-08-30 20:57:53 -0600)

----------------------------------------------------------------
Jeff Moyer (1):
iowatcher: don't add Q events to the io hash

 iowatcher/blkparse.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

---

Diff of recent changes:

iowatcher/blkparse.c +22 -10
index c7d1d65..41e20f0 100644
@@ -1099,16 +1099,28 @@ void add_pending_io(struct trace *trace, struct graph_line_data *gld)
 	if (action = __BLK_TA_QUEUE) {
 		if (io->sector = 0)
 			return;
-		if (trace->found_issue || trace->found_completion) {
-			pio = hash_queued_io(trace->io);
-			/*
-			 * When there are no ISSUE events count depth and
-			 * latency at least from queue events
-			 */
-			if (pio && !trace->found_issue) {
-				pio->dispatch_time = io->time;
-				goto account_io;
-			}
+		/*
+		 * If D (issue) events are available, use them for I/O
+		 * accounting.  Nothing needs to be done for Q.
+		 */
+		if (trace->found_issue)
+			return;
+		/*
+		 * If there are no D or C events, then all that can be
+		 * done is to account the Q event (and make sure not to
+		 * add the I/O to the hash, because it will never be
+		 * removed).
+		 */
+		if (!trace->found_completion)
+			goto account_io;
+		/*
+		 * When there are no ISSUE events, count depth and
+		 * latency from queue events.
+		 */
+		pio = hash_queued_io(trace->io);
+		if (pio) {
+			pio->dispatch_time = io->time;
+			goto account_io;
 		}
 		return;
 	}
#26 lore raw
In reply to Jens Axboe

The following changes since commit f011d96f260a2be5dcc2ad9f4d1bf2d591946723:

iowatcher: don't add Q events to the io hash (2018-08-30 20:57:53 -0600)

are available in the git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 10df4b691a68dd440547e393b6d241fc54fd2fad:

iowatcher: spawn NPROCESSORS_ONLN for rsvg-convert-s (2018-08-31 14:57:57 -0600)

----------------------------------------------------------------
Jeff Moyer (1):
iowatcher: spawn NPROCESSORS_ONLN for rsvg-convert-s

 iowatcher/main.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

---

Diff of recent changes:

iowatcher/main.c +7 -2
index 54325fb..4b97013 100644
@@ -1043,9 +1043,14 @@ static void system_check(const char *cmd)
 
 static void convert_movie_files(char *movie_dir)
 {
+	long nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+	if (nr_cpus < 0)
+		nr_cpus = 8;
+
 	fprintf(stderr, "Converting svg files in %s\n", movie_dir);
-	snprintf(line, line_len, "find %s -name \\*.svg | xargs -I{} -n 1 -P 8 rsvg-convert -o {}.png {}",
-		 movie_dir);
+	snprintf(line, line_len, "find %s -name \\*.svg | xargs -I{} -n 1 -P %ld rsvg-convert -o {}.png {}",
+		 movie_dir, nr_cpus);
 	system_check(line);
 }
 
#27 lore raw
In reply to Jens Axboe

The following changes since commit 10df4b691a68dd440547e393b6d241fc54fd2fad:

iowatcher: spawn NPROCESSORS_ONLN for rsvg-convert-s (2018-08-31 14:57:57 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to a7263b8fb22f07f4f1a3ec54f0c37193c5908b22:

blkparse: add support sort program by io event (2019-05-21 08:06:08 -0600)

----------------------------------------------------------------
Weiping Zhang (1):
blkparse: add support sort program by io event

 blkparse.c     | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 doc/blkparse.1 |  15 ++++++
 2 files changed, 169 insertions(+), 2 deletions(-)

---

Diff of recent changes:

blkparse.c +154 -2
index 227cc44..3de2ebe 100644
@@ -100,6 +100,19 @@ struct per_process_info {
 #define PPI_HASH_SHIFT	(8)
 #define PPI_HASH_SIZE	(1 << PPI_HASH_SHIFT)
 #define PPI_HASH_MASK	(PPI_HASH_SIZE - 1)
+
+enum {
+	SORT_PROG_EVENT_N,   /* Program Name */
+	SORT_PROG_EVENT_QKB, /* KB: Queued read and write */
+	SORT_PROG_EVENT_RKB, /* KB: Queued Read */
+	SORT_PROG_EVENT_WKB, /* KB: Queued Write */
+	SORT_PROG_EVENT_CKB, /* KB: Complete */
+	SORT_PROG_EVENT_QIO, /* IO: Queued read and write */
+	SORT_PROG_EVENT_RIO, /* IO: Queued Read */
+	SORT_PROG_EVENT_WIO, /* IO: Queued Write */
+	SORT_PROG_EVENT_CIO, /* IO: Complete */
+};
+
 static struct per_process_info *ppi_hash_table[PPI_HASH_SIZE];
 static struct per_process_info *ppi_list;
 static int ppi_list_entries;
@@ -189,6 +202,12 @@ static struct option l_opts[] = {
 		.flag = NULL,
 		.val = 's'
 	},
+	{
+		.name = "sort-program-stats",
+		.has_arg = required_argument,
+		.flag = NULL,
+		.val = 'S'
+	},
 	{
 		.name = "track-ios",
 		.has_arg = no_argument,
@@ -269,6 +288,7 @@ static unsigned long long stopwatch_end = -1ULL;	/* "infinity" */
 static unsigned long read_sequence;
 
 static int per_process_stats;
+static int per_process_stats_event = SORT_PROG_EVENT_N;
 static int per_device_and_cpu_stats = 1;
 static int track_ios;
 static int ppi_hash_by_pid = 1;
@@ -1758,6 +1778,88 @@ static int ppi_name_compare(const void *p1, const void *p2)
 	return res;
 }
 
+static int ppi_event_compare(const void *p1, const void *p2)
+{
+	struct per_process_info *ppi1 = *((struct per_process_info **) p1);
+	struct per_process_info *ppi2 = *((struct per_process_info **) p2);
+	struct io_stats *ios1 = &ppi1->io_stats;
+	struct io_stats *ios2 = &ppi2->io_stats;
+	unsigned long io1, io2;
+	unsigned long long kb1,kb2;
+	int sort_by_kb = 1;
+
+	io1 = io2 = 0;
+	kb1 = kb2 = 0;
+
+	switch (per_process_stats_event) {
+	case SORT_PROG_EVENT_QKB: /* KB: Queued read and write */
+		kb1 = ios1->qwrite_kb + (ios1->qwrite_b>>10) +
+			ios1->qread_kb + (ios1->qread_b>>10);
+		kb2 = ios2->qwrite_kb + (ios2->qwrite_b>>10) +
+			ios2->qread_kb + (ios2->qread_b>>10);
+		break;
+	case SORT_PROG_EVENT_RKB: /* KB: Queued Read */
+		kb1 = ios1->qread_kb + (ios1->qread_b>>10);
+		kb2 = ios2->qread_kb + (ios2->qread_b>>10);
+		break;
+	case SORT_PROG_EVENT_WKB: /* KB: Queued Write */
+		kb1 = ios1->qwrite_kb + (ios1->qwrite_b>>10);
+		kb2 = ios2->qwrite_kb + (ios2->qwrite_b>>10);
+		break;
+	case SORT_PROG_EVENT_CKB: /* KB: Complete */
+		kb1 = ios1->cwrite_kb + (ios1->cwrite_b>>10) +
+			ios1->cread_kb + (ios1->cread_b>>10);
+		kb2 = ios2->cwrite_kb + (ios2->cwrite_b>>10) +
+			ios2->cread_kb + (ios2->cread_b>>10);
+		break;
+	case SORT_PROG_EVENT_QIO: /* IO: Queued read and write */
+		sort_by_kb = 0;
+		io1 = ios1->qreads + ios1->qwrites;
+		io2 = ios2->qreads + ios2->qwrites;
+		break;
+	case SORT_PROG_EVENT_RIO: /* IO: Queued Read */
+		sort_by_kb = 0;
+		io1 = ios1->qreads;
+		io2 = ios2->qreads;
+		break;
+	case SORT_PROG_EVENT_WIO: /* IO: Queued Write */
+		sort_by_kb = 0;
+		io1 = ios1->qwrites;
+		io2 = ios2->qwrites;
+		break;
+	case SORT_PROG_EVENT_CIO: /* IO: Complete */
+		sort_by_kb = 0;
+		io1 = ios1->creads + ios1->cwrites;
+		io2 = ios2->creads + ios2->cwrites;
+		break;
+	}
+
+
+	/* compare kb */
+	if (sort_by_kb) {
+		if (kb1 > kb2)
+			return 1;
+		else if (kb1 = kb2)
+			return 0;
+		return -1;
+	}
+
+	/* compare io */
+	if (io1 > io2)
+		return 1;
+	else if (io1 = io2)
+		return 0;
+	return -1;
+}
+
+static int ppi_compare(const void *p1, const void *p2)
+{
+	if (per_process_stats_event = SORT_PROG_EVENT_N)
+		return ppi_name_compare(p1, p2);
+
+	return ppi_event_compare(p1, p2);
+}
+
 static void sort_process_list(void)
 {
 	struct per_process_info **ppis;
@@ -1772,7 +1874,7 @@ static void sort_process_list(void)
 		ppi = ppi->list_next;
 	}
 
-	qsort(ppis, ppi_list_entries, sizeof(ppi), ppi_name_compare);
+	qsort(ppis, ppi_list_entries, sizeof(ppi), ppi_compare);
 
 	i = ppi_list_entries - 1;
 	ppi_list = NULL;
@@ -2730,7 +2832,46 @@ static int is_pipe(const char *str)
 	return 0;
 }
 
-#define S_OPTS  "a:A:b:D:d:f:F:hi:o:Oqstw:vVM"
+static int get_program_sort_event(const char *str)
+{
+	char evt = str[0];
+
+	switch (evt) {
+	case 'N':
+		per_process_stats_event = SORT_PROG_EVENT_N;
+		break;
+	case 'Q':
+		per_process_stats_event = SORT_PROG_EVENT_QKB;
+		break;
+	case 'q':
+		per_process_stats_event = SORT_PROG_EVENT_QIO;
+		break;
+	case 'R':
+		per_process_stats_event = SORT_PROG_EVENT_RKB;
+		break;
+	case 'r':
+		per_process_stats_event = SORT_PROG_EVENT_RIO;
+		break;
+	case 'W':
+		per_process_stats_event = SORT_PROG_EVENT_WKB;
+		break;
+	case 'w':
+		per_process_stats_event = SORT_PROG_EVENT_WIO;
+		break;
+	case 'C':
+		per_process_stats_event = SORT_PROG_EVENT_CKB;
+		break;
+	case 'c':
+		per_process_stats_event = SORT_PROG_EVENT_CIO;
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+#define S_OPTS  "a:A:b:D:d:f:F:hi:o:OqsS:tw:vVM"
 static char usage_str[] =    "\n\n" \
 	"-i <file>           | --input=<file>\n" \
 	"[ -a <action field> | --act-mask=<action field> ]\n" \
@@ -2745,6 +2886,7 @@ static char usage_str[] =    "\n\n" \
 	"[ -O                | --no-text-output ]\n" \
 	"[ -q                | --quiet ]\n" \
 	"[ -s                | --per-program-stats ]\n" \
+	"[ -S <event>        | --sort-program-stats=<event> ]\n" \
 	"[ -t                | --track-ios ]\n" \
 	"[ -w <time>         | --stopwatch=<time> ]\n" \
 	"[ -M                | --no-msgs\n" \
@@ -2764,6 +2906,11 @@ static char usage_str[] =    "\n\n" \
 	"\t-O Do NOT output text data\n" \
 	"\t-q Quiet. Don't display any stats at the end of the trace\n" \
 	"\t-s Show per-program io statistics\n" \
+	"\t-S Show per-program io statistics sorted by N/Q/q/R/r/W/w/C/c\n" \
+	"\t   N:Name, Q/q:Queued(read & write), R/r:Queued Read, W/w:Queued Write, C/c:Complete.\n" \
+	"\t   Sort programs by how much data(KB): Q,R,W,C.\n" \
+	"\t   Sort programs by how many IO operations: q,r,w,c.\n" \
+	"\t   if -S was used, the -s parameter will be ignored.\n" \
 	"\t-t Track individual ios. Will tell you the time a request took\n" \
 	"\t   to get queued, to get dispatched, and to get completed\n" \
 	"\t-w Only parse data between the given time interval in seconds.\n" \
@@ -2830,6 +2977,11 @@ int main(int argc, char *argv[])
 		case 's':
 			per_process_stats = 1;
 			break;
+		case 'S':
+			per_process_stats = 1;
+			if (get_program_sort_event(optarg))
+				return 1;
+			break;
 		case 't':
 			track_ios = 1;
 			break;
doc/blkparse.1 +15 -0
index cb21fea..627b7b1 100644
@@ -165,6 +165,21 @@ Quiet mode
 Displays data sorted by program
 .RE
 
+\-S \fIevent\fR
+.br
+\-\-sort\-program\-stats=\fIevent\fR
+.br
+.RS
+Displays each program's data sorted by program name or io event, like
+Queued, Read, Write and Complete. When \-S is specified the \-s will be ignored.
+The capital letters Q,R,W,C stand for KB, then q/r/w/c stand for IO.
+
+If you want to soct programs by how many data they queued, you can use:
+
+blkparse -i sda.blktrace. -q \-S Q \-o sda.parse
+.RE
+
+
 \-t
 .br
 \-\-track\-ios
#28 lore raw
In reply to Jens Axboe

The following changes since commit a7263b8fb22f07f4f1a3ec54f0c37193c5908b22:

blkparse: add support sort program by io event (2019-05-21 08:06:08 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 667ac92a1a72b6038f0fae4acfc6a280fd69697b:

btreplay: fix device IO remap functionality (2019-09-16 10:30:23 -0600)

----------------------------------------------------------------
Ignat Korchagin (1):
btreplay: fix device IO remap functionality

 btreplay/btreplay.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

---

Diff of recent changes:

btreplay/btreplay.c +2 -2
index edaf81f..23cc2a9 100644
@@ -645,7 +645,7 @@ static void find_input_devs(char *idir)
 static void read_map_devs(char *file_name)
 {
 	FILE *fp;
-	char from_dev[256], to_dev[256];
+	char *from_dev, *to_dev;
 
 	fp = fopen(file_name, "r");
 	if (!fp) {
@@ -653,7 +653,7 @@ static void read_map_devs(char *file_name)
 		/*NOTREACHED*/
 	}
 
-	while (fscanf(fp, "%s %s", from_dev, to_dev) = 2) {
+	while (fscanf(fp, "%ms %ms", &from_dev, &to_dev) = 2) {
 		struct map_dev *mdp = malloc(sizeof(*mdp));
 
 		mdp->from_dev = from_dev;
#29 lore raw
In reply to Jens Axboe

The following changes since commit 667ac92a1a72b6038f0fae4acfc6a280fd69697b:

btreplay: fix device IO remap functionality (2019-09-16 10:30:23 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 9c73da91540b27adaaf56065629e831cc50c5a3d:

doc: tex: add absolute timestamp printing option (2019-09-25 00:22:13 -0600)

----------------------------------------------------------------
Hiroaki Mihara (4):
blkparse: man: add absolute timestamp printing option
blkparse: split off the timestamp correction code in to a separate function
blkparse: fix absolute timestamp when reading from file
doc: tex: add absolute timestamp printing option

 blkparse.c       | 37 +++++++++++++++++++++++++------------
 doc/blkparse.1   |  3 +++
 doc/blktrace.tex |  1 +
 3 files changed, 29 insertions(+), 12 deletions(-)

---

Diff of recent changes:

blkparse.c +25 -12
index 3de2ebe..28bdf15 100644
@@ -2022,6 +2022,22 @@ static void show_device_and_cpu_stats(void)
 	}
 }
 
+static void correct_abs_start_time(void)
+{
+	long delta = genesis_time - start_timestamp;
+
+	abs_start_time.tv_sec  += SECONDS(delta);
+	abs_start_time.tv_nsec += NANO_SECONDS(delta);
+	if (abs_start_time.tv_nsec < 0) {
+		abs_start_time.tv_nsec += 1000000000;
+		abs_start_time.tv_sec -= 1;
+	} else
+	if (abs_start_time.tv_nsec > 1000000000) {
+		abs_start_time.tv_nsec -= 1000000000;
+		abs_start_time.tv_sec += 1;
+	}
+}
+
 static void find_genesis(void)
 {
 	struct trace *t = trace_list;
@@ -2039,18 +2055,7 @@ static void find_genesis(void)
 	 */
 	if (start_timestamp
 	 && start_timestamp != genesis_time) {
-		long delta = genesis_time - start_timestamp;
-
-		abs_start_time.tv_sec  += SECONDS(delta);
-		abs_start_time.tv_nsec += NANO_SECONDS(delta);
-		if (abs_start_time.tv_nsec < 0) {
-			abs_start_time.tv_nsec += 1000000000;
-			abs_start_time.tv_sec -= 1;
-		} else
-		if (abs_start_time.tv_nsec > 1000000000) {
-			abs_start_time.tv_nsec -= 1000000000;
-			abs_start_time.tv_sec += 1;
-		}
+		correct_abs_start_time();
 	}
 }
 
@@ -2704,6 +2709,14 @@ static int do_file(void)
 	if (ms_head)
 		genesis_time = ms_peek_time(ms_head);
 
+	/*
+	 * Correct abs_start_time if necessary
+	 */
+	if (start_timestamp
+	 && start_timestamp != genesis_time) {
+		correct_abs_start_time();
+	}
+
 	/*
 	 * Keep processing traces while any are left
 	 */
doc/blkparse.1 +3 -0
index 627b7b1..e494b6e 100644
@@ -368,6 +368,9 @@ Elapsed value in microseconds (\fI\-t\fR command line option)
 .IP \fBU\fR 4
 Payload unsigned integer
 
+.IP \fBz\fR 4
+The absolute time, as local time in your time zone, with no date displayed
+
 .PP
 Note that the user can optionally specify field display width, and optionally a
 left-aligned specifier. These precede field specifiers, with a '%' character,
doc/blktrace.tex +1 -0
index 4d8278e..3647c75 100644
@@ -613,6 +613,7 @@ the event's device \\
 \emph{T} & Time stamp (seconds) \\ \hline
 \emph{u} & Elapsed value in microseconds (\emph{-t} command line option) \\ \hline
 \emph{U} & Payload unsigned integer \\ \hline
+\emph{z} & Absolute time stamp \\ \hline
 \end{tabular}
 
 Note that the user can optionally specify field display width, and
#30 lore raw
In reply to Jens Axboe

The following changes since commit 9c73da91540b27adaaf56065629e831cc50c5a3d:

doc: tex: add absolute timestamp printing option (2019-09-25 00:22:13 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to f4f8ef7cdea138cfaa2f3ca0ee31fa23d3bcf1cc:

fix parallel build of btt and blkiomon (2020-01-16 13:33:59 -0700)

----------------------------------------------------------------
Gwendal Grignou (1):
fix parallel build of btt and blkiomon

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

Makefile +1 -1
index 5917814..eb3c6a1 100644
@@ -14,7 +14,7 @@ all: $(ALL) $(SUBDIRS)
 
 # We always descend into subdirs because they contain their own dependency
 # information which we don't track in this top level Makefile.
-$(SUBDIRS):
+$(SUBDIRS): $(PROGS)
 	$(MAKE) -C $@
 .PHONY: $(SUBDIRS)
 
#31 lore raw
In reply to Jens Axboe

The following changes since commit f4f8ef7cdea138cfaa2f3ca0ee31fa23d3bcf1cc:

fix parallel build of btt and blkiomon (2020-01-16 13:33:59 -0700)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to db4f6340e04716285ea56fe26d76381c3adabe58:

btt_plot.py: Use with open() as ... context manager (2020-03-20 15:53:50 -0600)

----------------------------------------------------------------
Vincent Legoll (10):
btt_plot.py: Use sum() instead of open-coding it to compute list average bno_plot.py: Use shutil.rmtree() instead of os.system('/bin/rm') bno_plot.py: Use with open() as ... context manager to automatically handle close() btt_plot.py: Fix pylint: wrong-import-order
btt_plot.py: Fix pylint: len-as-condition
btt_plot.py: Fix pylint: singleton-comparison
btt_plot.py: Fix pylint: no-else-return
bno_plot.py: Fix pylint: len-as-condition
bno_plot.py: Fix pylint: singleton-comparison
btt_plot.py: Use with open() as ... context manager

 btt/bno_plot.py | 27 +++++++++++++-------------
 btt/btt_plot.py | 60 ++++++++++++++++++++++++++++-----------------------------
 2 files changed, 42 insertions(+), 45 deletions(-)

---

Diff of recent changes:

btt/bno_plot.py +13 -14
index f05cfdc..3aa4e19 100644
@@ -40,7 +40,7 @@ To exit the plotter, enter 'quit' or ^D at the 'gnuplot> ' prompt.
 
 from __future__ import absolute_import
 from __future__ import print_function
-import getopt, glob, os, sys, tempfile
+import getopt, glob, os, sys, tempfile, shutil
 
 verbose	= 0
 cmds	= """
@@ -76,7 +76,7 @@ def parse_args(in_args):
 		elif o in ('-K', '--keys-below'):
 			keys_below = True
 
-	if len(args) > 0:	bnos = args
+	if args:	bnos = args
 	else:			bnos = glob.glob('blknos*[rw].dat')
 
 	return (bnos, keys_below)
@@ -98,21 +98,20 @@ if __name__ = '__main__':
 	for f in bnos:
 		t = '%s/%s' % (tmpdir, f)
 
-		fo = open(t, 'w')
-		for line in open(f, 'r'):
-			fld = line.split(None)
-			print(fld[0], fld[1], int(fld[2])-int(fld[1]), file=fo)
-		fo.close()
+		with open(t, 'w') as fo:
+			with open(f, 'r') as fi:
+				for line in fi:
+					fld = line.split(None)
+					print(fld[0], fld[1], int(fld[2])-int(fld[1]), file=fo)
 
 		t = t[t.rfind('/')+1:]
-		if plot_cmd = None: plot_cmd = "splot '%s'" % t
+		if plot_cmd is None: plot_cmd = "splot '%s'" % t
 		else:                plot_cmd = "%s,'%s'" % (plot_cmd, t)
 
-	fo = open('%s/plot.cmds' % tmpdir, 'w')
-	print(cmds, file=fo)
-	if len(bnos) > 10 or keys_below: print('set key below', file=fo)
-	print(plot_cmd, file=fo)
-	fo.close()
+	with open('%s/plot.cmds' % tmpdir, 'w') as fo:
+		print(cmds, file=fo)
+		if len(bnos) > 10 or keys_below: print('set key below', file=fo)
+		print(plot_cmd, file=fo)
 
 	pid = os.fork()
 	if pid = 0:
@@ -125,4 +124,4 @@ if __name__ = '__main__':
 		sys.exit(1)
 
 	os.waitpid(pid, 0)
-	os.system('/bin/rm -rf ' + tmpdir)
+	shutil.rmtree(tmpdir)
btt/btt_plot.py +29 -31

146 lines not on this page · raw message

#32 lore raw
In reply to Jens Axboe

The following changes since commit db4f6340e04716285ea56fe26d76381c3adabe58:

btt_plot.py: Use with open() as ... context manager (2020-03-20 15:53:50 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to e81829a565162d41e2f551dc5e0f74f22f319554:

blkparse: Fix up the sector and length of split completions (2020-05-07 12:22:37 -0600)

----------------------------------------------------------------
Andreas Gruenbacher (4):
blkparse: Fix device in event tracking error messages
blkparse: Allow request tracking on non md/dm devices
blkparse: Initialize and test for undefined request tracking timestamps
blkparse: Fix up the sector and length of split completions

 blkparse.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 130 insertions(+), 39 deletions(-)

---

Diff of recent changes:

blkparse.c +130 -39
index 28bdf15..796059b 100644
@@ -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>
@@ -261,17 +262,21 @@ static struct trace *t_alloc_list;
 /*
  * for tracking individual ios
  */
-struct io_track {
-	struct rb_node rb_node;
-
+struct io_track_req {
 	struct process_pid_map *ppm;
-	__u64 sector;
 	unsigned long long allocation_time;
 	unsigned long long queue_time;
 	unsigned long long dispatch_time;
 	unsigned long long completion_time;
 };
 
+struct io_track {
+	struct rb_node rb_node;
+	struct io_track_req *req;
+	struct io_track *next;
+	__u64 sector;
+};
+
 static int ndevices;
 static struct per_dev_info *devices;
 static char *get_dev_name(struct per_dev_info *, char *, int);
@@ -326,6 +331,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) {
@@ -976,6 +996,11 @@ static struct io_track *__find_track(struct per_dev_info *pdi, __u64 sector)
 	return NULL;
 }
 
+static inline struct io_track *first_iot(struct io_track_req *req)
+{
+	return (struct io_track *)(req + 1);
+}
+
 static struct io_track *find_track(struct per_dev_info *pdi, pid_t pid,
 				   __u64 sector)
 {
@@ -983,10 +1008,19 @@ static struct io_track *find_track(struct per_dev_info *pdi, pid_t pid,
 
 	iot = __find_track(pdi, sector);
 	if (!iot) {
-		iot = malloc(sizeof(*iot));
-		iot->ppm = find_ppm(pid);
-		if (!iot->ppm)
-			iot->ppm = add_ppm_hash(pid, "unknown");
+		struct io_track_req *req;
+
+		req = malloc(sizeof(*req) + sizeof(*iot));
+		req->ppm = find_ppm(pid);
+		if (!req->ppm)
+			req->ppm = add_ppm_hash(pid, "unknown");
+		req->allocation_time = -1ULL;
+		req->queue_time = -1ULL;
+		req->dispatch_time = -1ULL;
+		req->completion_time = -1ULL;
+		iot = first_iot(req);
+		iot->req = req;
+		iot->next = NULL;
 		iot->sector = sector;
 		track_rb_insert(pdi, iot);
 	}
@@ -1006,7 +1040,7 @@ static void log_track_frontmerge(struct per_dev_info *pdi,
 	if (!iot) {
 		if (verbose)
 			fprintf(stderr, "merge not found for (%d,%d): %llu\n",
-				MAJOR(pdi->dev), MINOR(pdi->dev),
+				MAJOR(t->device), MINOR(t->device),
 				(unsigned long long) t->sector + t_sec(t));
 		return;
 	}
@@ -1019,19 +1053,16 @@ static void log_track_frontmerge(struct per_dev_info *pdi,
 static void log_track_getrq(struct per_dev_info *pdi, struct blk_io_trace *t)
 {
 	struct io_track *iot;
+	struct io_track_req *req;
 
 	if (!track_ios)
 		return;
 
 	iot = find_track(pdi, t->pid, t->sector);
-	iot->allocation_time = t->time;
-}
-
-static inline int is_remapper(struct per_dev_info *pdi)
-{
-	int major = MAJOR(pdi->dev);
-
-	return (major = 253 || major = 9);
+	req = iot->req;
+	io_warn_unless(t, req->allocation_time = -1ULL,
+		       "confused about %s time", "allocation");
+	req->allocation_time = t->time;
 }
 
 /*
@@ -1041,14 +1072,34 @@ static inline int is_remapper(struct per_dev_info *pdi)
 static void log_track_queue(struct per_dev_info *pdi, struct blk_io_trace *t)
 {
 	struct io_track *iot;
+	struct io_track_req *req;
 
 	if (!track_ios)
 		return;
-	if (!is_remapper(pdi))
-		return;
 
 	iot = find_track(pdi, t->pid, t->sector);
-	iot->dispatch_time = t->time;
+	req = iot->req;
+	io_warn_unless(t, req->dispatch_time = -1ULL,
+		       "confused about %s time", "dispatch");
+	req->dispatch_time = t->time;
+}
+
+static void log_track_split(struct per_dev_info *pdi, struct blk_io_trace *t)
+{
+	struct io_track *iot, *split;
+
+	/*
+	 * With a split request, the completion event will refer to the last
+	 * part of the original request, but other events might refer to other
+	 * parts.
+	 */
+	iot = find_track(pdi, t->pid, t->sector);
+	split = malloc(sizeof(*iot));
+	split->req = iot->req;
+	split->next = iot->next;
+	iot->next = split;
+	split->sector = iot->sector + t_sec(t);
+	track_rb_insert(pdi, split);
 }
 
 /*
@@ -1059,20 +1110,24 @@ static unsigned long long log_track_insert(struct per_dev_info *pdi,
 {
 	unsigned long long elapsed;
 	struct io_track *iot;
+	struct io_track_req *req;
 
 	if (!track_ios)
 		return -1;
 
 	iot = find_track(pdi, t->pid, t->sector);
-	iot->queue_time = t->time;
+	req = iot->req;
+	io_warn_unless(t, req->queue_time = -1ULL,
+		       "confused about %s time", "queue");
+	req->queue_time = t->time;
 
-	if (!iot->allocation_time)
+	if (req->allocation_time = -1ULL)
 		return -1;
 
-	elapsed = iot->queue_time - iot->allocation_time;
+	elapsed = req->queue_time - req->allocation_time;
 
 	if (per_process_stats) {
-		struct per_process_info *ppi = find_ppi(iot->ppm->pid);
+		struct per_process_info *ppi = find_ppi(req->ppm->pid);
 		int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
 		if (ppi && elapsed > ppi->longest_allocation_wait[w])
@@ -1088,8 +1143,9 @@ 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;
+	struct io_track_req *req;
 
 	if (!track_ios)
 		return -1;
@@ -1100,16 +1156,20 @@ static unsigned long long log_track_issue(struct per_dev_info *pdi,
 	if (!iot) {
 		if (verbose)
 			fprintf(stderr, "issue not found for (%d,%d): %llu\n",
-				MAJOR(pdi->dev), MINOR(pdi->dev),
+				MAJOR(t->device), MINOR(t->device),
 				(unsigned long long) t->sector);
 		return -1;
 	}
 
-	iot->dispatch_time = t->time;
-	elapsed = iot->dispatch_time - iot->queue_time;
+	req = iot->req;
+	io_warn_unless(t, req->dispatch_time = -1ULL,
+		       "confused about %s time", "dispatch");
+	req->dispatch_time = t->time;
+	if (req->queue_time != -1ULL)
+		elapsed = req->dispatch_time - req->queue_time;
 
-	if (per_process_stats) {
-		struct per_process_info *ppi = find_ppi(iot->ppm->pid);
+	if (elapsed != -1ULL && per_process_stats) {
+		struct per_process_info *ppi = find_ppi(req->ppm->pid);
 		int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
 		if (ppi && elapsed > ppi->longest_dispatch_wait[w])
@@ -1119,14 +1179,34 @@ static unsigned long long log_track_issue(struct per_dev_info *pdi,
 	return elapsed;
 }
 
+static void fixup_complete(struct per_dev_info *pdi, struct blk_io_trace *t)
+{
+	struct io_track *iot;
+	__u64 start_sector;
+
+	iot = __find_track(pdi, t->sector);
+	if (!iot)
+		return;
+
+	/*
+	 * When a split io completes, the sector and length of the completion
+	 * refer to the last part of the original request.  Fix the sector and
+	 * length of the complete event to match the original request.
+	 */
+	start_sector = first_iot(iot->req)->sector;
+	t->bytes += (t->sector - start_sector) << 9;
+	t->sector = start_sector;
+}
+
 /*
  * return time between dispatch and complete
  */
 static unsigned long long log_track_complete(struct per_dev_info *pdi,
 					     struct blk_io_trace *t)
 {
-	unsigned long long elapsed;
-	struct io_track *iot;
+	unsigned long long elapsed = -1ULL;
+	struct io_track *iot, *next;
+	struct io_track_req *req;
 
 	if (!track_ios)
 		return -1;
@@ -1135,16 +1215,20 @@ static unsigned long long log_track_complete(struct per_dev_info *pdi,
 	if (!iot) {
 		if (verbose)
 			fprintf(stderr,"complete not found for (%d,%d): %llu\n",
-				MAJOR(pdi->dev), MINOR(pdi->dev),
+				MAJOR(t->device), MINOR(t->device),
 				(unsigned long long) t->sector);
 		return -1;
 	}
 
-	iot->completion_time = t->time;
-	elapsed = iot->completion_time - iot->dispatch_time;
+	req = iot->req;
+	io_warn_unless(t, req->completion_time = -1ULL,
+		       "confused about %s time", "completion");
+	req->completion_time = t->time;
+	if (req->dispatch_time != -1ULL)
+		elapsed = req->completion_time - req->dispatch_time;
 
-	if (per_process_stats) {
-		struct per_process_info *ppi = find_ppi(iot->ppm->pid);
+	if (elapsed != -1ULL && per_process_stats) {
+		struct per_process_info *ppi = find_ppi(req->ppm->pid);
 		int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
 		if (ppi && elapsed > ppi->longest_completion_wait[w])
@@ -1154,8 +1238,13 @@ static unsigned long long log_track_complete(struct per_dev_info *pdi,
 	/*
 	 * kill the trace, we don't need it after completion
 	 */
-	rb_erase(&iot->rb_node, &pdi->rb_track);
-	free(iot);
+	for (iot = first_iot(req); iot; iot = next) {
+		next = iot->next;
+		rb_erase(&iot->rb_node, &pdi->rb_track);
+		if (iot != first_iot(req))
+			free(iot);
+	}
+	free(req);
 
 	return elapsed;
 }
@@ -1606,6 +1695,7 @@ static void dump_trace_fs(struct blk_io_trace *t, struct per_dev_info *pdi,
 		case __BLK_TA_COMPLETE:
 			if (pdi->cur_depth[w])
 				pdi->cur_depth[w]--;
+			fixup_complete(pdi, t);
 			account_c(t, pci, w, t->bytes);
 			log_complete(pdi, pci, t, "C");
 			break;
@@ -1621,6 +1711,7 @@ static void dump_trace_fs(struct blk_io_trace *t, struct per_dev_info *pdi,
 			log_unplug(pci, t, "UT");
 			break;
 		case __BLK_TA_SPLIT:
+			log_track_split(pdi, t);
 			log_split(pci, t, "X");
 			break;
 		case __BLK_TA_BOUNCE:
#33 lore raw
In reply to Jens Axboe

The following changes since commit e81829a565162d41e2f551dc5e0f74f22f319554:

blkparse: Fix up the sector and length of split completions (2020-05-07 12:22:37 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to a021a33b405b5101eec6c389e1dacd7934fdd35e:

blkparse: Print PID information for TN_MESSAGE events (2020-05-20 07:38:26 -0600)

----------------------------------------------------------------
Jan Kara (4):
blkparse: Handle cgroup information
iowatcher: Use blktrace_api.h
iowatcher: Handle cgroup information
blkparse: Print PID information for TN_MESSAGE events

 blkparse.c           |  41 ++++++++++------
 blkparse_fmt.c       |  15 ++++++
 blktrace_api.h       |  10 ++++
 doc/blkparse.1       |   4 ++
 doc/blktrace.tex     |   3 ++
 iowatcher/blkparse.c | 134 +++++++++------------------------------------------
 6 files changed, 81 insertions(+), 126 deletions(-)

---

Diff of recent changes:

blkparse.c +26 -15
index 796059b..33dd023 100644
@@ -617,7 +617,7 @@ static void handle_notify(struct blk_io_trace *bit)
 	void	*payload = (caddr_t) bit + sizeof(*bit);
 	__u32	two32[2];
 
-	switch (bit->action) {
+	switch (bit->action & ~__BLK_TN_CGROUP) {
 	case BLK_TN_PROCESS:
 		add_ppm_hash(bit->pid, payload);
 		break;
@@ -643,16 +643,27 @@ static void handle_notify(struct blk_io_trace *bit)
 	case BLK_TN_MESSAGE:
 		if (bit->pdu_len > 0) {
 			char msg[bit->pdu_len+1];
+			int len = bit->pdu_len;
+			char cgidstr[24];
 
-			memcpy(msg, (char *)payload, bit->pdu_len);
-			msg[bit->pdu_len] = '\0';
+			cgidstr[0] = 0;
+			if (bit->action & __BLK_TN_CGROUP) {
+				struct blk_io_cgroup_payload *cgid = payload;
+
+				sprintf(cgidstr, "%x,%x ", cgid->ino,
+					cgid->gen);
+				payload += sizeof(struct blk_io_cgroup_payload);
+				len -= sizeof(struct blk_io_cgroup_payload);
+			}
+			memcpy(msg, (char *)payload, len);
+			msg[len] = '\0';
 
 			fprintf(ofp,
-				"%3d,%-3d %2d %8s %5d.%09lu %5u %2s %3s %s\n",
+				"%3d,%-3d %2d %8s %5d.%09lu %5u %s%2s %3s %s\n",
 				MAJOR(bit->device), MINOR(bit->device),
-				bit->cpu, "0", (int) SECONDS(bit->time),
-				(unsigned long) NANO_SECONDS(bit->time),
-				0, "m", "N", msg);
+				bit->cpu, "0", (int)SECONDS(bit->time),
+				(unsigned long)NANO_SECONDS(bit->time),
+				bit->pid, cgidstr, "m", "N", msg);
 		}
 		break;
 
@@ -1600,7 +1611,7 @@ static void dump_trace_pc(struct blk_io_trace *t, struct per_dev_info *pdi,
 			  struct per_cpu_info *pci)
 {
 	int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
-	int act = t->action & 0xffff;
+	int act = (t->action & 0xffff) & ~__BLK_TA_CGROUP;
 
 	switch (act) {
 		case __BLK_TA_QUEUE:
@@ -1649,7 +1660,7 @@ static void dump_trace_fs(struct blk_io_trace *t, struct per_dev_info *pdi,
 			  struct per_cpu_info *pci)
 {
 	int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
-	int act = t->action & 0xffff;
+	int act = (t->action & 0xffff) & ~__BLK_TA_CGROUP;
 
 	switch (act) {
 		case __BLK_TA_QUEUE:
@@ -1734,7 +1745,7 @@ static void dump_trace(struct blk_io_trace *t, struct per_cpu_info *pci,
 		       struct per_dev_info *pdi)
 {
 	if (text_output) {
-		if (t->action = BLK_TN_MESSAGE)
+		if ((t->action & ~__BLK_TN_CGROUP) = BLK_TN_MESSAGE)
 			handle_notify(t);
 		else if (t->action & BLK_TC_ACT(BLK_TC_PC))
 			dump_trace_pc(t, pdi, pci);
@@ -1749,7 +1760,7 @@ static void dump_trace(struct blk_io_trace *t, struct per_cpu_info *pci,
 
 	if (bin_output_msgs ||
 			    !(t->action & BLK_TC_ACT(BLK_TC_NOTIFY) &&
-			      t->action = BLK_TN_MESSAGE))
+			      (t->action & ~__BLK_TN_CGROUP) = BLK_TN_MESSAGE))
 		output_binary(t, sizeof(*t) + t->pdu_len);
 }
 
@@ -2325,7 +2336,7 @@ static void show_entries_rb(int force)
 			break;
 		}
 
-		if (!(bit->action = BLK_TN_MESSAGE) &&
+		if (!((bit->action & ~__BLK_TN_CGROUP) = BLK_TN_MESSAGE) &&
 		    check_sequence(pdi, t, force))
 			break;
 
@@ -2337,7 +2348,7 @@ static void show_entries_rb(int force)
 		if (!pci || pci->cpu != bit->cpu)
 			pci = get_cpu_info(pdi, bit->cpu);
 
-		if (!(bit->action = BLK_TN_MESSAGE))
+		if (!((bit->action & ~__BLK_TN_CGROUP) = BLK_TN_MESSAGE))
 			pci->last_sequence = bit->sequence;
 
 		pci->nelems++;
@@ -2471,7 +2482,7 @@ static int read_events(int fd, int always_block, int *fdblock)
 		/*
 		 * not a real trace, so grab and handle it here
 		 */
-		if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && bit->action != BLK_TN_MESSAGE) {
+		if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && (bit->action & ~__BLK_TN_CGROUP) != BLK_TN_MESSAGE) {
 			handle_notify(bit);
 			output_binary(bit, sizeof(*bit) + bit->pdu_len);
 			continue;
@@ -2620,7 +2631,7 @@ static int ms_prime(struct ms_stream *msp)
 			continue;
 		}
 
-		if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && bit->action != BLK_TN_MESSAGE) {
+		if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && (bit->action & ~__BLK_TN_CGROUP) != BLK_TN_MESSAGE) {
 			handle_notify(bit);
 			output_binary(bit, sizeof(*bit) + bit->pdu_len);
 			bit_free(bit);
blkparse_fmt.c +14 -0
index c42e6d7..df2f6ce 100644
@@ -205,6 +205,21 @@ static void print_field(char *act, struct per_cpu_info *pci,
 	case 'e':
 		fprintf(ofp, strcat(format, "d"), t->error);
 		break;
+	case 'g': {
+		char cgidstr[24];
+		u32 ino = 0, gen = 0;
+
+		if (t->action & __BLK_TA_CGROUP) {
+			struct blk_io_cgroup_payload *cgid +				(struct blk_io_cgroup_payload *)pdu_buf;
+
+			ino = cgid->ino;
+			gen = cgid->gen;
+		}
+		sprintf(cgidstr, "%x,%x", ino, gen);
+		fprintf(ofp, strcat(format, "s"), cgidstr);
+		break;
+	}
 	case 'M':
 		fprintf(ofp, strcat(format, "d"), MAJOR(t->device));
 		break;
blktrace_api.h +10 -0
index b222218..8c760b8 100644
@@ -51,6 +51,7 @@ enum {
 	__BLK_TA_REMAP,			/* bio was remapped */
 	__BLK_TA_ABORT,			/* request aborted */
 	__BLK_TA_DRV_DATA,		/* binary driver data */
+	__BLK_TA_CGROUP = 1 << 8,
 };
 
 /*
@@ -60,6 +61,7 @@ enum blktrace_notify {
 	__BLK_TN_PROCESS = 0,		/* establish pid/name mapping */
 	__BLK_TN_TIMESTAMP,		/* include system clock */
 	__BLK_TN_MESSAGE,               /* Character string message */
+	__BLK_TN_CGROUP = __BLK_TA_CGROUP,
 };
 
 /*
@@ -116,6 +118,14 @@ struct blk_io_trace_remap {
 	__u64 sector_from;
 };
 
+/*
+ * Payload with originating cgroup info
+ */
+struct blk_io_cgroup_payload {
+	__u32 ino;
+	__u32 gen;
+};
+
 /*
  * User setup structure passed with BLKSTARTTRACE
  */
doc/blkparse.1 +4 -0
index e494b6e..4c26baf 100644
@@ -332,6 +332,10 @@ the event's device (separated by a comma).
 .IP \fBe\fR 4
 Error value
 
+.IP \fBg\fR 4
+Cgroup identifier of the cgroup that generated the IO. Note that this requires
+appropriate kernel support (kernel version at least 4.14).
+
 .IP \fBm\fR 4
 Minor number of event's device.
 
doc/blktrace.tex +3 -0
index 3647c75..836ac4a 100644
@@ -601,6 +601,9 @@ Specifier & \\ \hline\hline
 the event's device \\
          & (separated by a comma). \\ \hline
 \emph{e} & Error value \\ \hline
+\emph{g} & Cgroup identifier of the cgroup that generated the IO. Note that this requires
+appropriate \\
+         & kernel support (kernel version at least 4.14). \\ \hline
 \emph{m} & Minor number of event's device. \\ \hline
 \emph{M} & Major number of event's device. \\ \hline
 \emph{n} & Number of blocks \\ \hline
iowatcher/blkparse.c +23 -111

182 lines not on this page · raw message

#34 lore raw
In reply to Jens Axboe

The following changes since commit a021a33b405b5101eec6c389e1dacd7934fdd35e:

blkparse: Print PID information for TN_MESSAGE events (2020-05-20 07:38:26 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 2ec0bb0b725305025dcc3e3f195894040e2dab90:

blktrace: inclusive terminology (2021-02-19 09:42:41 -0700)

----------------------------------------------------------------
Eric Sandeen (1):
blktrace: inclusive terminology

 blkparse_fmt.c | 4 ++--
 blktrace.c     | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

---

Diff of recent changes:

blkparse_fmt.c +2 -2
index df2f6ce..9b83d1d 100644
@@ -276,12 +276,12 @@ static void print_field(char *act, struct per_cpu_info *pci,
 static char *parse_field(char *act, struct per_cpu_info *pci,
 			 struct blk_io_trace *t, unsigned long long elapsed,
 			 int pdu_len, unsigned char *pdu_buf,
-			 char *master_format)
+			 char *primary_format)
 {
 	int minus = 0;
 	int has_w = 0;
 	int width = 0;
-	char *p = master_format;
+	char *p = primary_format;
 
 	if (*p = '-') {
 		minus = 1;
blktrace.c +1 -1
index d0d271f..82a6aad 100644
@@ -307,7 +307,7 @@ static pthread_mutex_t dp_mutex = PTHREAD_MUTEX_INITIALIZER;
 static volatile int dp_entries;
 
 /*
- * These synchronize master / thread interactions.
+ * These synchronize main / thread interactions.
  */
 static pthread_cond_t mt_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t mt_mutex = PTHREAD_MUTEX_INITIALIZER;
#35 lore raw
In reply to Jens Axboe

The following changes since commit 2ec0bb0b725305025dcc3e3f195894040e2dab90:

blktrace: inclusive terminology (2021-02-19 09:42:41 -0700)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to dc24c67dfbbd11a3221034557548061e7d2c602f:

blkparse: Print time when trace was started (2021-04-19 11:55:04 -0600)

----------------------------------------------------------------
Jan Kara (1):
blkparse: Print time when trace was started

 blkparse.c | 2 ++
 1 file changed, 2 insertions(+)

---

Diff of recent changes:

blkparse.c +2 -0
index 33dd023..1d7ae95 100644
@@ -32,6 +32,7 @@
 #include <signal.h>
 #include <locale.h>
 #include <libgen.h>
+#include <time.h>
 
 #include "blktrace.h"
 #include "rbtree.h"
@@ -2888,6 +2889,7 @@ static void show_stats(void)
 
 	if (per_device_and_cpu_stats)
 		show_device_and_cpu_stats();
+	fprintf(ofp, "Trace started at %s\n", ctime(&abs_start_time.tv_sec));
 
 	fflush(ofp);
 }
#36 lore raw
In reply to Jens Axboe

The following changes since commit dc24c67dfbbd11a3221034557548061e7d2c602f:

blkparse: Print time when trace was started (2021-04-19 11:55:04 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 366d30b9cdb20345c5d064af850d686da79b89eb:

blktrace 1.3.0 (2021-06-14 08:55:52 -0600)

----------------------------------------------------------------
Jens Axboe (1):

      blktrace 1.3.0
 blkparse.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

---

Diff of recent changes:

blkparse.c +1 -1
index 1d7ae95..f88204a 100644
@@ -38,7 +38,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.2.0";
+static char blkparse_version[] = "1.3.0";
 
 struct skip_info {
 	unsigned long start, end;
#37 lore raw
In reply to Jens Axboe

The following changes since commit 366d30b9cdb20345c5d064af850d686da79b89eb:

blktrace 1.3.0 (2021-06-14 08:55:52 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 3a1b1366d30375cdb0f5b299df4edda0c8ba3bcc:

blktrace: exit directly when nthreads_running != ncpus in run_tracers() (2021-06-28 13:41:32 -0600)

----------------------------------------------------------------
lijinlin (1):

      blktrace: exit directly when nthreads_running != ncpus in run_tracers()
 blktrace.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

---

Diff of recent changes:

blktrace.c +3 -1
index 82a6aad..3444fbb 100644
@@ -2705,8 +2705,10 @@ static int run_tracers(void)
 			printf("blktrace: connected!\n");
 		if (stop_watch)
 			alarm(stop_watch);
-	} else
+	} else {
 		stop_tracers();
+		done = 1;
+	}
 
 	wait_tracers();
 	if (nthreads_running = ncpus)
#38 lore raw
In reply to Jens Axboe

The following changes since commit 3a1b1366d30375cdb0f5b299df4edda0c8ba3bcc:

blktrace: exit directly when nthreads_running != ncpus in run_tracers() (2021-06-28 13:41:32 -0600)

are available in the Git repository at:

git://git.kernel.dk/blktrace.git master

for you to fetch changes up to 7f5d2c5173d72018aa29c583c9291ef10abaf8df:

blkparse: fix incorrectly sized memset in check_cpu_map (2021-10-21 08:45:17 -0600)

----------------------------------------------------------------
Jeff Mahoney (2):
blkparse: skip check_cpu_map with pipe input
blkparse: fix incorrectly sized memset in check_cpu_map

 blkparse.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

---

Diff of recent changes:

blkparse.c +5 -2
index f88204a..9d2029a 100644
@@ -2229,11 +2229,14 @@ static int check_cpu_map(struct per_dev_info *pdi)
 	unsigned int i;
 	int ret, cpu;
 
+	/* Pipe input doesn't do CPU online tracking. */
+	if (!pdi->cpu_map_max)
+		return 0;
+
 	/*
 	 * create a map of the cpus we have traces for
 	 */
-	cpu_map = malloc(pdi->cpu_map_max / sizeof(long));
-	memset(cpu_map, 0, sizeof(*cpu_map));
+	cpu_map = calloc(1, pdi->cpu_map_max / sizeof(long));
 	n = rb_first(&rb_sort_root);
 	while (n) {
 		__t = rb_entry(n, struct trace, rb_node);