* [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher
@ 2026-07-16 11:04 Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 01/11] btt: use blk_io_trace2 internally Johannes Thumshirn
` (10 more replies)
0 siblings, 11 replies; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
We had an internal report that the new blktrace format does not work
with the btt tool.
This is because I simply forgot to update these tools. Do so now and
sorry for all the inconvenience it might have brought.
Johannes Thumshirn (11):
btt: use blk_io_trace2 internally
btt: natively parse blk_io_trace2
blktrace: add option to request a specific trace protocol version
blkrawverify: use blk_io_trace2 internally
blkrawverify: natively parse blk_io_trace2
blkiomon: use blk_io_trace2 internally
blkiomon: natively parse blk_io_trace2
iowatcher: use blk_io_trace2 internally
iowatcher: natively parse blk_io_trace2
btreplay: support blk_io_trace2 in btrecord
blkparse: add option to emit a specific trace protocol version
blkiomon.c | 93 +++++++++++++++++++--------
blkparse.c | 66 ++++++++++++++++---
blkrawverify.c | 69 +++++++++++++++-----
blktrace.c | 30 ++++++++-
blktrace.h | 20 ++++++
btreplay/btrecord.c | 83 +++++++++++++++++++-----
btt/globals.h | 4 +-
btt/mmap.c | 134 ++++++++++++++++++++++++++++++++++++--
doc/blkparse.1 | 7 ++
doc/blktrace.8 | 7 ++
iowatcher/blkparse.c | 150 ++++++++++++++++++++++++++++++++-----------
iowatcher/blkparse.h | 3 +-
12 files changed, 551 insertions(+), 115 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 01/11] btt: use blk_io_trace2 internally
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 11:43 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 02/11] btt: natively parse blk_io_trace2 Johannes Thumshirn
` (9 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Use 'struct blk_io_trace2' as internal representation for a captured
blktrace.
This implies the conversion of 'struct blk_io_trace' into 'struct
blk_io_trace2' when reading the trace from the binary file.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
btt/globals.h | 4 ++--
btt/mmap.c | 22 ++++++++++++++++------
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/btt/globals.h b/btt/globals.h
index 22a1cb060149..f37b3cbd2edf 100644
--- a/btt/globals.h
+++ b/btt/globals.h
@@ -158,7 +158,7 @@ struct io {
__u64 s_time;
__u32 d_nsec, c_nsec;
- struct blk_io_trace t;
+ struct blk_io_trace2 t;
int linked;
enum iop_type type;
@@ -260,7 +260,7 @@ void clean_allocs(void);
/* mmap.c */
void setup_ifile(char *fname);
void cleanup_ifile(void);
-int next_trace(struct blk_io_trace *t, void **pdu);
+int next_trace(struct blk_io_trace2 *t, void **pdu);
double pct_done(void);
/* output.c */
diff --git a/btt/mmap.c b/btt/mmap.c
index 9d4eb3d62fda..766a32b6c9e8 100644
--- a/btt/mmap.c
+++ b/btt/mmap.c
@@ -47,15 +47,25 @@ static inline size_t min_len(size_t a, size_t b)
}
static inline size_t convert_to_cpu(struct blk_io_trace *t,
- struct blk_io_trace *tp,
+ struct blk_io_trace2 *tp,
void **pdu)
{
if (data_is_native == -1)
check_data_endianness(t->magic);
- if (data_is_native)
- memcpy(tp, t, sizeof(*tp));
- else {
+ if (data_is_native) {
+ tp->magic = t->magic;
+ tp->sequence = t->sequence;
+ tp->time = t->time;
+ tp->sector = t->sector;
+ tp->bytes = t->bytes;
+ tp->action = t->action;
+ tp->pid = t->pid;
+ tp->device = t->device;
+ tp->cpu = t->cpu;
+ tp->error = t->error;
+ tp->pdu_len = t->pdu_len;
+ } else {
tp->magic = be32_to_cpu(t->magic);
tp->sequence = be32_to_cpu(t->sequence);
tp->time = be64_to_cpu(t->time);
@@ -75,7 +85,7 @@ static inline size_t convert_to_cpu(struct blk_io_trace *t,
} else
*pdu = NULL;
- return sizeof(*tp) + tp->pdu_len;
+ return sizeof(*t) + tp->pdu_len;
}
static int move_map(void)
@@ -127,7 +137,7 @@ void cleanup_ifile(void)
close(fd);
}
-int next_trace(struct blk_io_trace *t, void **pdu)
+int next_trace(struct blk_io_trace2 *t, void **pdu)
{
size_t this_len;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 02/11] btt: natively parse blk_io_trace2
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 01/11] btt: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 11:47 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 03/11] blktrace: add option to request a specific trace protocol version Johannes Thumshirn
` (8 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Natively parse 'struct blk_io_trace2' from a blktrace binary.
Detect the layout by parsing the input as both 'struct blk_io_trace' and
'struct blk_io_trace2' and using whichever interprets the trace stream
cleanly.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
btt/mmap.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 112 insertions(+), 2 deletions(-)
diff --git a/btt/mmap.c b/btt/mmap.c
index 766a32b6c9e8..b0a80f4f8e7a 100644
--- a/btt/mmap.c
+++ b/btt/mmap.c
@@ -36,8 +36,9 @@ static int fd;
static void *cur_map = MAP_FAILED;
static off_t cur_min, cur, cur_max, total_size;
static size_t len;
-static struct blk_io_trace *next_t;
+static struct blk_io_trace2 *next_t;
static long pgsz;
+static int trace_version;
int data_is_native = -1;
@@ -88,6 +89,38 @@ static inline size_t convert_to_cpu(struct blk_io_trace *t,
return sizeof(*t) + tp->pdu_len;
}
+static inline size_t convert_to_cpu2(struct blk_io_trace2 *t,
+ struct blk_io_trace2 *tp,
+ void **pdu)
+{
+ if (data_is_native == -1)
+ check_data_endianness(t->magic);
+
+ if (data_is_native)
+ memcpy(tp, t, sizeof(*tp));
+ else {
+ tp->magic = be32_to_cpu(t->magic);
+ tp->sequence = be32_to_cpu(t->sequence);
+ tp->time = be64_to_cpu(t->time);
+ tp->sector = be64_to_cpu(t->sector);
+ tp->bytes = be32_to_cpu(t->bytes);
+ tp->action = be64_to_cpu(t->action);
+ tp->pid = be32_to_cpu(t->pid);
+ tp->device = be32_to_cpu(t->device);
+ tp->cpu = be32_to_cpu(t->cpu);
+ tp->error = be16_to_cpu(t->error);
+ tp->pdu_len = be16_to_cpu(t->pdu_len);
+ }
+
+ if (tp->pdu_len) {
+ *pdu = malloc(tp->pdu_len);
+ memcpy(*pdu, t+1, tp->pdu_len);
+ } else
+ *pdu = NULL;
+
+ return sizeof(*t) + tp->pdu_len;
+}
+
static int move_map(void)
{
if (cur_map != MAP_FAILED)
@@ -137,6 +170,72 @@ void cleanup_ifile(void)
close(fd);
}
+static inline int magic_ok(__u32 magic)
+{
+ if (!data_is_native)
+ magic = be32_to_cpu(magic);
+
+ return CHECK_MAGIC(magic);
+}
+
+static int count_traces(int version)
+{
+ size_t hdr = (version == SUPPORTED_VERSION2) ?
+ sizeof(struct blk_io_trace2) : sizeof(struct blk_io_trace);
+ off_t pos = cur;
+ int n = 0;
+
+ while (n < 16) {
+ void *p;
+ __u16 pdu_len;
+
+ if (pos == total_size)
+ break;
+ if ((pos + (off_t)hdr) > cur_max)
+ break;
+
+ p = cur_map + (pos - cur_min);
+ if (!magic_ok(((struct blk_io_trace *)p)->magic))
+ break;
+
+ if (version == SUPPORTED_VERSION2)
+ pdu_len = ((struct blk_io_trace2 *)p)->pdu_len;
+ else
+ pdu_len = ((struct blk_io_trace *)p)->pdu_len;
+ if (!data_is_native)
+ pdu_len = be16_to_cpu(pdu_len);
+
+ pos += hdr + pdu_len;
+ n++;
+ }
+
+ return n;
+}
+
+/*
+ * New blkparse always emits 'struct blk_io_trace2', while an old blkparse
+ * emits 'struct blk_io_trace'. As both share the same magic for version 1
+ * traces, the on-disk layout cannot be told apart by the version alone. Pick
+ * the layout that parses the input cleanly.
+ */
+static int detect_trace_version(void)
+{
+ __u32 magic;
+
+ if (data_is_native)
+ magic = next_t->magic;
+ else
+ magic = be32_to_cpu(next_t->magic);
+
+ if ((magic & 0xff) == SUPPORTED_VERSION2)
+ return SUPPORTED_VERSION2;
+
+ if (count_traces(SUPPORTED_VERSION2) >= count_traces(SUPPORTED_VERSION))
+ return SUPPORTED_VERSION2;
+
+ return SUPPORTED_VERSION;
+}
+
int next_trace(struct blk_io_trace2 *t, void **pdu)
{
size_t this_len;
@@ -148,7 +247,18 @@ int next_trace(struct blk_io_trace2 *t, void **pdu)
}
next_t = cur_map + (cur - cur_min);
- this_len = convert_to_cpu(next_t, t, pdu);
+
+ if (data_is_native == -1)
+ check_data_endianness(next_t->magic);
+
+ if (!trace_version)
+ trace_version = detect_trace_version();
+
+ if (trace_version == SUPPORTED_VERSION2)
+ this_len = convert_to_cpu2(next_t, t, pdu);
+ else
+ this_len = convert_to_cpu((struct blk_io_trace *) next_t,
+ t, pdu);
cur += this_len;
return 1;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 03/11] blktrace: add option to request a specific trace protocol version
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 01/11] btt: use blk_io_trace2 internally Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 02/11] btt: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 11:54 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 04/11] blkrawverify: use blk_io_trace2 internally Johannes Thumshirn
` (7 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Add the '--trace-version=<1|2>' command line option to select the trace
protocol version requested from the kernel. Requesting version 1 forces
blktrace to use the old BLKTRACESETUP ioctl, while version 2 (the
default) uses BLKTRACESETUP2.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blktrace.c | 30 ++++++++++++++++++++++++++++--
doc/blktrace.8 | 7 +++++++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/blktrace.c b/blktrace.c
index 72562fdc9d9e..35db26fd4e23 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -283,6 +283,7 @@ static unsigned long long act_mask = ~0U;
static int kill_running_trace;
static int stop_watch;
static int piped_output;
+static int v1;
static char *debugfs_path = "/sys/kernel/debug";
static char *output_name;
@@ -329,6 +330,10 @@ static int *cl_fds;
static int (*handle_pfds)(struct tracer *, int, int);
static int (*handle_list)(struct tracer_devpath_head *, struct list_head *);
+enum {
+ OPT_TRACE_VERSION = 256,
+};
+
#define S_OPTS "d:a:A:r:o:kw:vVb:n:D:lh:p:sI:"
static struct option l_opts[] = {
{
@@ -433,6 +438,12 @@ static struct option l_opts[] = {
.flag = NULL,
.val = 's'
},
+ {
+ .name = "trace-version",
+ .has_arg = required_argument,
+ .flag = NULL,
+ .val = OPT_TRACE_VERSION
+ },
{
.name = NULL,
}
@@ -455,6 +466,7 @@ static char usage_str[] = "\n\n" \
"[ -I <devs file> | --input-devs=<devs file>]\n" \
"[ -v <version> | --version]\n" \
"[ -V <version> | --version]\n" \
+ "[ --trace-version=<1|2> ]\n" \
"\t-d Use specified device. May also be given last after options\n" \
"\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
@@ -471,7 +483,8 @@ static char usage_str[] = "\n\n" \
"\t-s Make the network client NOT use sendfile() to transfer data\n" \
"\t-I Add devices found in <devs file>\n" \
"\t-v Print program version info\n" \
- "\t-V Print program version info\n\n";
+ "\t-V Print program version info\n" \
+ "\t--trace-version Request trace protocol version 1 or 2 from the kernel\n\n";
static void clear_events(struct pollfd *pfd)
{
@@ -2244,6 +2257,19 @@ static int handle_args(int argc, char *argv[])
case 's':
net_use_sendfile = 0;
break;
+ case OPT_TRACE_VERSION: {
+ int ver = atoi(optarg);
+
+ if (ver == 1)
+ v1 = 1;
+ else if (ver == 2)
+ v1 = 0;
+ else {
+ show_usage(argv[0]);
+ exit(1);
+ }
+ break;
+ }
default:
show_usage(argv[0]);
exit(1);
@@ -2714,7 +2740,7 @@ static int run_tracers(void)
if (net_mode == Net_client)
printf("blktrace: connecting to %s\n", hostname);
- if (setup_buts2()) {
+ if (v1 || setup_buts2()) {
if (setup_buts()) {
done = 1;
return 1;
diff --git a/doc/blktrace.8 b/doc/blktrace.8
index 820b03aa4c16..c502adcfaa9d 100644
--- a/doc/blktrace.8
+++ b/doc/blktrace.8
@@ -191,6 +191,13 @@ Outputs version
Sets run time to the number of seconds specified
.RE
+\-\-trace\-version=\fI1|2\fR
+.RS
+Selects the trace protocol version requested from the kernel. Requesting
+version 1 forces blktrace to use the old \fBBLKTRACESETUP\fR ioctl, while
+version 2 (the default) uses \fBBLKTRACESETUP2\fR.
+.RE
+
.SH FILTER MASKS
The following masks may be passed with the \fI\-a\fR command line
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 04/11] blkrawverify: use blk_io_trace2 internally
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (2 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 03/11] blktrace: add option to request a specific trace protocol version Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 11:55 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 05/11] blkrawverify: natively parse blk_io_trace2 Johannes Thumshirn
` (6 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Use 'struct blk_io_trace2' as internal representation for a captured
blktrace.
This implies the conversion of 'struct blk_io_trace' into 'struct
blk_io_trace2' when reading the trace from the binary file.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blkrawverify.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/blkrawverify.c b/blkrawverify.c
index 8e863cb39490..2a3aa609581f 100644
--- a/blkrawverify.c
+++ b/blkrawverify.c
@@ -102,7 +102,7 @@ static char *act_to_str(__u64 action)
return buf;
}
-static void dump_trace(FILE *ofp, char *prefix, struct blk_io_trace *bit)
+static void dump_trace(FILE *ofp, char *prefix, struct blk_io_trace2 *bit)
{
fprintf(ofp, " Dump %s\n", prefix);
fprintf(ofp, " %8s: %08x\n", "magic", bit->magic);
@@ -123,13 +123,13 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
{
# define SWAP_BITS() do { \
if (bit_save) { \
- struct blk_io_trace *tmp = bit_save; \
+ struct blk_io_trace2 *tmp = bit_save; \
bit_save = bit; \
bit = tmp; \
} \
else { \
bit_save = bit; \
- bit = malloc(sizeof(struct blk_io_trace)); \
+ bit = malloc(sizeof(struct blk_io_trace2)); \
} \
} while (0)
@@ -145,8 +145,9 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
FILE *ifp, *ofp;
__u32 save_device = 0, save_sequence = 0;
__u64 save_time = 0;
- struct blk_io_trace *bit_save = NULL;
- struct blk_io_trace *bit = malloc(sizeof(struct blk_io_trace));
+ struct blk_io_trace bit1;
+ struct blk_io_trace2 *bit_save = NULL;
+ struct blk_io_trace2 *bit = malloc(sizeof(struct blk_io_trace2));
unsigned int ngood = 0;
unsigned int nbad = 0;
unsigned int nbad_trace = 0, nbad_pdu = 0, nbad_cpu = 0;
@@ -172,16 +173,28 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
}
ofp = *fp;
- while ((n = fread(bit, sizeof(struct blk_io_trace), 1, ifp)) == 1) {
+ while ((n = fread(&bit1, sizeof(struct blk_io_trace), 1, ifp)) == 1) {
if (ferror(ifp)) {
clearerr(ifp);
perror("fread");
break;
}
if (data_is_native == -1)
- check_data_endianness(bit->magic);
-
- bit_trace_to_cpu(bit);
+ check_data_endianness(bit1.magic);
+
+ bit_trace_to_cpu(&bit1);
+
+ bit->magic = bit1.magic;
+ bit->sequence = bit1.sequence;
+ bit->time = bit1.time;
+ bit->sector = bit1.sector;
+ bit->bytes = bit1.bytes;
+ bit->action = bit1.action;
+ bit->pid = bit1.pid;
+ bit->device = bit1.device;
+ bit->cpu = bit1.cpu;
+ bit->error = bit1.error;
+ bit->pdu_len = bit1.pdu_len;
if (!CHECK_MAGIC(bit->magic)) {
INC_BAD("bad trace");
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 05/11] blkrawverify: natively parse blk_io_trace2
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (3 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 04/11] blkrawverify: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:04 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 06/11] blkiomon: use blk_io_trace2 internally Johannes Thumshirn
` (5 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Natively parse 'struct blk_io_trace2' from a blktrace binary.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blkrawverify.c | 72 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 24 deletions(-)
diff --git a/blkrawverify.c b/blkrawverify.c
index 2a3aa609581f..7ef3c075aeef 100644
--- a/blkrawverify.c
+++ b/blkrawverify.c
@@ -119,6 +119,52 @@ static void dump_trace(FILE *ofp, char *prefix, struct blk_io_trace2 *bit)
MINOR(bit->device));
}
+static int read_trace(FILE *ifp, struct blk_io_trace2 *bit)
+{
+ struct blk_io_trace bit1;
+ struct blk_io_trace2 bit2;
+ __u32 magic;
+ int version;
+ void *p;
+
+ if (fread(&magic, sizeof(magic), 1, ifp) != 1)
+ return 0;
+
+ if (data_is_native == -1)
+ check_data_endianness(magic);
+
+ version = (data_is_native ? magic : be32_to_cpu(magic)) & 0xff;
+
+ if (version == SUPPORTED_VERSION2) {
+ bit2.magic = magic;
+ p = (void *) ((u8 *)&bit2 + sizeof(__u32));
+ if (fread(p, sizeof(bit2) - sizeof(__u32), 1, ifp) != 1)
+ return 0;
+ bit2_trace_to_cpu(&bit2);
+ *bit = bit2;
+ } else {
+ bit1.magic = magic;
+ p = (void *) ((u8 *)&bit1 + sizeof(__u32));
+ if (fread(p, sizeof(bit1) - sizeof(__u32), 1, ifp) != 1)
+ return 0;
+ bit_trace_to_cpu(&bit1);
+
+ bit->magic = bit1.magic;
+ bit->sequence = bit1.sequence;
+ bit->time = bit1.time;
+ bit->sector = bit1.sector;
+ bit->bytes = bit1.bytes;
+ bit->action = bit1.action;
+ bit->pid = bit1.pid;
+ bit->device = bit1.device;
+ bit->cpu = bit1.cpu;
+ bit->error = bit1.error;
+ bit->pdu_len = bit1.pdu_len;
+ }
+
+ return 1;
+}
+
static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
{
# define SWAP_BITS() do { \
@@ -145,7 +191,6 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
FILE *ifp, *ofp;
__u32 save_device = 0, save_sequence = 0;
__u64 save_time = 0;
- struct blk_io_trace bit1;
struct blk_io_trace2 *bit_save = NULL;
struct blk_io_trace2 *bit = malloc(sizeof(struct blk_io_trace2));
unsigned int ngood = 0;
@@ -173,39 +218,18 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
}
ofp = *fp;
- while ((n = fread(&bit1, sizeof(struct blk_io_trace), 1, ifp)) == 1) {
+ while (read_trace(ifp, bit)) {
if (ferror(ifp)) {
clearerr(ifp);
perror("fread");
break;
}
- if (data_is_native == -1)
- check_data_endianness(bit1.magic);
-
- bit_trace_to_cpu(&bit1);
-
- bit->magic = bit1.magic;
- bit->sequence = bit1.sequence;
- bit->time = bit1.time;
- bit->sector = bit1.sector;
- bit->bytes = bit1.bytes;
- bit->action = bit1.action;
- bit->pid = bit1.pid;
- bit->device = bit1.device;
- bit->cpu = bit1.cpu;
- bit->error = bit1.error;
- bit->pdu_len = bit1.pdu_len;
if (!CHECK_MAGIC(bit->magic)) {
INC_BAD("bad trace");
continue;
}
- if ((bit->magic & 0xff) != SUPPORTED_VERSION) {
- fprintf(stderr, "unsupported trace version\n");
- break;
- }
-
if (bit->pdu_len) {
char *pdu_buf;
@@ -258,7 +282,7 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
SWAP_BITS();
}
- if (n == 0 && !feof(ifp))
+ if (!feof(ifp))
fprintf(stderr,"%s: fread failed %d/%s\n",
file, errno, strerror(errno));
fclose(ifp);
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 06/11] blkiomon: use blk_io_trace2 internally
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (4 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 05/11] blkrawverify: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:05 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 07/11] blkiomon: natively parse blk_io_trace2 Johannes Thumshirn
` (4 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Use 'struct blk_io_trace2' as internal representation for a captured
blktrace.
This implies the conversion of 'struct blk_io_trace' into 'struct
blk_io_trace2' when reading the trace from the binary file.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blkiomon.c | 46 ++++++++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/blkiomon.c b/blkiomon.c
index 9defa2c3fd43..32580a435fc8 100644
--- a/blkiomon.c
+++ b/blkiomon.c
@@ -42,7 +42,7 @@
#include "blkiomon.h"
struct trace {
- struct blk_io_trace bit;
+ struct blk_io_trace2 bit;
struct rb_node node;
struct trace *next;
long sequence;
@@ -105,7 +105,7 @@ static long leftover = 0, driverdata = 0, match = 0, mismatch = 0, sequence = 0;
static void dump_bit(struct trace *t, const char *descr)
{
- struct blk_io_trace *bit = &t->bit;
+ struct blk_io_trace2 *bit = &t->bit;
if (!debug.fn)
return;
@@ -116,7 +116,7 @@ static void dump_bit(struct trace *t, const char *descr)
fprintf(debug.fp, "time %16ld\n", (unsigned long)bit->time);
fprintf(debug.fp, "sector %16ld\n", (unsigned long)bit->sector);
fprintf(debug.fp, "bytes %16d\n", bit->bytes);
- fprintf(debug.fp, "action %16x\n", bit->action);
+ fprintf(debug.fp, "action %16llx\n", (unsigned long long)bit->action);
fprintf(debug.fp, "pid %16d\n", bit->pid);
fprintf(debug.fp, "device %16d\n", bit->device);
fprintf(debug.fp, "cpu %16d\n", bit->cpu);
@@ -128,8 +128,8 @@ static void dump_bit(struct trace *t, const char *descr)
static void dump_bits(struct trace *t1, struct trace *t2, const char *descr)
{
- struct blk_io_trace *bit1 = &t1->bit;
- struct blk_io_trace *bit2 = &t2->bit;
+ struct blk_io_trace2 *bit1 = &t1->bit;
+ struct blk_io_trace2 *bit2 = &t2->bit;
if (!debug.fn)
return;
@@ -143,7 +143,9 @@ static void dump_bits(struct trace *t1, struct trace *t2, const char *descr)
fprintf(debug.fp, "sector %16ld %16ld\n",
(unsigned long)bit1->sector, (unsigned long)bit2->sector);
fprintf(debug.fp, "bytes %16d %16d\n", bit1->bytes, bit2->bytes);
- fprintf(debug.fp, "action %16x %16x\n", bit1->action, bit2->action);
+ fprintf(debug.fp, "action %16llx %16llx\n",
+ (unsigned long long)bit1->action,
+ (unsigned long long)bit2->action);
fprintf(debug.fp, "pid %16d %16d\n", bit1->pid, bit2->pid);
fprintf(debug.fp, "device %16d %16d\n", bit1->device, bit2->device);
fprintf(debug.fp, "cpu %16d %16d\n", bit1->cpu, bit2->cpu);
@@ -305,8 +307,8 @@ static void *blkiomon_interval(void *data)
#define BLK_DATADIR(a) (((a) >> BLK_TC_SHIFT) & (BLK_TC_READ | BLK_TC_WRITE))
-static int blkiomon_account(struct blk_io_trace *bit_d,
- struct blk_io_trace *bit_c)
+static int blkiomon_account(struct blk_io_trace2 *bit_d,
+ struct blk_io_trace2 *bit_c)
{
struct dstat *dstat;
struct blkiomon_stat *p;
@@ -371,7 +373,7 @@ static void blkiomon_store_trace(struct trace *t)
thash[i] = t;
}
-static struct trace *blkiomon_fetch_trace(struct blk_io_trace *bit)
+static struct trace *blkiomon_fetch_trace(struct blk_io_trace2 *bit)
{
int i = bit->sector % TRACE_HASH_SIZE;
struct trace *t, *prev = NULL;
@@ -428,7 +430,7 @@ static struct trace *blkiomon_do_trace(struct trace *t)
return t_old;
}
-static int blkiomon_dump_drvdata(struct blk_io_trace *bit, void *pdu_buf)
+static int blkiomon_dump_drvdata(struct blk_io_trace2 *bit, void *pdu_buf)
{
if (!drvdata.fn)
return 0;
@@ -451,8 +453,10 @@ failed:
static int blkiomon_do_fifo(void)
{
struct trace *t;
- struct blk_io_trace *bit;
+ struct blk_io_trace2 *bit;
+ struct blk_io_trace bit1;
void *pdu_buf = NULL;
+ void *p;
t = blkiomon_alloc_trace();
if (!t)
@@ -468,13 +472,14 @@ static int blkiomon_do_fifo(void)
"blkiomon: could not read trace");
break;
}
- if (fread(bit, sizeof(*bit), 1, ifp) != 1) {
+ bit1.magic = magic;
+ p = (void *) ((u8 *)&bit1 + sizeof(__u32));
+ if (fread(p, sizeof(bit1) - sizeof(__u32), 1, ifp) != 1) {
if (!feof(ifp))
fprintf(stderr,
"blkiomon: could not read trace");
break;
}
- bit->magic = magic;
if (ferror(ifp)) {
clearerr(ifp);
fprintf(stderr, "blkiomon: error while reading trace");
@@ -487,7 +492,20 @@ static int blkiomon_do_fifo(void)
}
/* endianess */
- bit_trace_to_cpu(bit);
+ bit_trace_to_cpu(&bit1);
+
+ bit->magic = bit1.magic;
+ bit->sequence = bit1.sequence;
+ bit->time = bit1.time;
+ bit->sector = bit1.sector;
+ bit->bytes = bit1.bytes;
+ bit->action = bit1.action;
+ bit->pid = bit1.pid;
+ bit->device = bit1.device;
+ bit->cpu = bit1.cpu;
+ bit->error = bit1.error;
+ bit->pdu_len = bit1.pdu_len;
+
if (verify_trace(bit->magic)) {
fprintf(stderr, "blkiomon: bad trace\n");
break;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 07/11] blkiomon: natively parse blk_io_trace2
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (5 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 06/11] blkiomon: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:06 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 08/11] iowatcher: use blk_io_trace2 internally Johannes Thumshirn
` (3 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Natively parse 'struct blk_io_trace2' from a blktrace binary.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blkiomon.c | 79 +++++++++++++++++++++++++++++++++++-------------------
1 file changed, 52 insertions(+), 27 deletions(-)
diff --git a/blkiomon.c b/blkiomon.c
index 32580a435fc8..081d1a87dfdc 100644
--- a/blkiomon.c
+++ b/blkiomon.c
@@ -465,6 +465,7 @@ static int blkiomon_do_fifo(void)
while (up) {
__u32 magic;
+ int version;
if (fread(&magic, sizeof(magic), 1, ifp) != 1) {
if (!feof(ifp))
@@ -472,39 +473,63 @@ static int blkiomon_do_fifo(void)
"blkiomon: could not read trace");
break;
}
- bit1.magic = magic;
- p = (void *) ((u8 *)&bit1 + sizeof(__u32));
- if (fread(p, sizeof(bit1) - sizeof(__u32), 1, ifp) != 1) {
- if (!feof(ifp))
- fprintf(stderr,
- "blkiomon: could not read trace");
- break;
- }
- if (ferror(ifp)) {
- clearerr(ifp);
- fprintf(stderr, "blkiomon: error while reading trace");
- break;
- }
if (data_is_native == -1 && check_data_endianness(magic)) {
fprintf(stderr, "blkiomon: endianess problem\n");
break;
}
- /* endianess */
- bit_trace_to_cpu(&bit1);
-
- bit->magic = bit1.magic;
- bit->sequence = bit1.sequence;
- bit->time = bit1.time;
- bit->sector = bit1.sector;
- bit->bytes = bit1.bytes;
- bit->action = bit1.action;
- bit->pid = bit1.pid;
- bit->device = bit1.device;
- bit->cpu = bit1.cpu;
- bit->error = bit1.error;
- bit->pdu_len = bit1.pdu_len;
+ version = (data_is_native ? magic : be32_to_cpu(magic)) & 0xff;
+
+ if (version == SUPPORTED_VERSION2) {
+ bit->magic = magic;
+ p = (void *) ((u8 *)bit + sizeof(__u32));
+ if (fread(p, sizeof(*bit) - sizeof(__u32), 1, ifp) != 1) {
+ if (!feof(ifp))
+ fprintf(stderr,
+ "blkiomon: could not read trace");
+ break;
+ }
+ if (ferror(ifp)) {
+ clearerr(ifp);
+ fprintf(stderr,
+ "blkiomon: error while reading trace");
+ break;
+ }
+
+ /* endianess */
+ bit2_trace_to_cpu(bit);
+ } else {
+ bit1.magic = magic;
+ p = (void *) ((u8 *)&bit1 + sizeof(__u32));
+ if (fread(p, sizeof(bit1) - sizeof(__u32), 1, ifp) != 1) {
+ if (!feof(ifp))
+ fprintf(stderr,
+ "blkiomon: could not read trace");
+ break;
+ }
+ if (ferror(ifp)) {
+ clearerr(ifp);
+ fprintf(stderr,
+ "blkiomon: error while reading trace");
+ break;
+ }
+
+ /* endianess */
+ bit_trace_to_cpu(&bit1);
+
+ bit->magic = bit1.magic;
+ bit->sequence = bit1.sequence;
+ bit->time = bit1.time;
+ bit->sector = bit1.sector;
+ bit->bytes = bit1.bytes;
+ bit->action = bit1.action;
+ bit->pid = bit1.pid;
+ bit->device = bit1.device;
+ bit->cpu = bit1.cpu;
+ bit->error = bit1.error;
+ bit->pdu_len = bit1.pdu_len;
+ }
if (verify_trace(bit->magic)) {
fprintf(stderr, "blkiomon: bad trace\n");
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 08/11] iowatcher: use blk_io_trace2 internally
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (6 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 07/11] blkiomon: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:07 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 09/11] iowatcher: natively parse blk_io_trace2 Johannes Thumshirn
` (2 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Use 'struct blk_io_trace2' as internal representation for a captured
blktrace.
This implies the conversion of 'struct blk_io_trace' into 'struct
blk_io_trace2' when reading the trace from the binary file.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
iowatcher/blkparse.c | 83 ++++++++++++++++++++++++--------------------
iowatcher/blkparse.h | 2 +-
2 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/iowatcher/blkparse.c b/iowatcher/blkparse.c
index 0518083a1089..ee1c2c511de6 100644
--- a/iowatcher/blkparse.c
+++ b/iowatcher/blkparse.c
@@ -146,7 +146,7 @@ static struct pending_io *io_hash_table_search(u64 sector, u32 dev)
return NULL;
}
-static struct pending_io *hash_queued_io(struct blk_io_trace *io)
+static struct pending_io *hash_queued_io(struct blk_io_trace2 *io)
{
struct pending_io *pio;
int ret;
@@ -165,7 +165,7 @@ static struct pending_io *hash_queued_io(struct blk_io_trace *io)
return pio;
}
-static struct pending_io *hash_dispatched_io(struct blk_io_trace *io)
+static struct pending_io *hash_dispatched_io(struct blk_io_trace2 *io)
{
struct pending_io *pio;
@@ -179,7 +179,7 @@ static struct pending_io *hash_dispatched_io(struct blk_io_trace *io)
return pio;
}
-static struct pending_io *hash_completed_io(struct blk_io_trace *io)
+static struct pending_io *hash_completed_io(struct blk_io_trace2 *io)
{
struct pending_io *pio;
@@ -257,7 +257,7 @@ static struct pid_map *process_hash_insert(u32 pid, char *name)
static void handle_notify(struct trace *trace)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
void *payload = (char *)io + sizeof(*io);
int pdu_len = io->pdu_len;
u32 two32[2];
@@ -288,27 +288,53 @@ static void handle_notify(struct trace *trace)
}
}
+static void trace_convert_io(struct trace *trace)
+{
+ struct blk_io_trace *old = (struct blk_io_trace *)trace->cur;
+ struct blk_io_trace2 *io;
+
+ io = realloc(trace->io, sizeof(struct blk_io_trace2) + old->pdu_len);
+
+ io->magic = old->magic;
+ io->sequence = old->sequence;
+ io->time = old->time;
+ io->sector = old->sector;
+ io->bytes = old->bytes;
+ io->action = old->action;
+ io->pid = old->pid;
+ io->device = old->device;
+ io->cpu = old->cpu;
+ io->error = old->error;
+ io->pdu_len = old->pdu_len;
+
+ if (io->pdu_len)
+ memcpy((char *)io + sizeof(*io),
+ (char *)old + sizeof(*old), old->pdu_len);
+
+ trace->io = io;
+}
+
int next_record(struct trace *trace)
{
int skip = trace->io->pdu_len;
u64 offset;
- trace->cur += sizeof(*trace->io) + skip;
+ trace->cur += sizeof(struct blk_io_trace) + skip;
offset = trace->cur - trace->start;
if (offset >= trace->len)
return 1;
- trace->io = (struct blk_io_trace *)trace->cur;
+ trace_convert_io(trace);
return 0;
}
void first_record(struct trace *trace)
{
trace->cur = trace->start;
- trace->io = (struct blk_io_trace *)trace->cur;
+ trace_convert_io(trace);
}
-static int is_io_event(struct blk_io_trace *test)
+static int is_io_event(struct blk_io_trace2 *test)
{
char *message;
if (!(test->action & BLK_TC_ACT(BLK_TC_NOTIFY)))
@@ -332,30 +358,11 @@ static int is_io_event(struct blk_io_trace *test)
u64 find_last_time(struct trace *trace)
{
- char *p = trace->start + trace->len;
- struct blk_io_trace *test;
- int search_len = 0;
u64 found = 0;
- if (trace->len < sizeof(*trace->io))
+ if (trace->len < sizeof(struct blk_io_trace))
return 0;
- p -= sizeof(*trace->io);
- while (p >= trace->start) {
- test = (struct blk_io_trace *)p;
- if (CHECK_MAGIC(test) && is_io_event(test)) {
- u64 offset = p - trace->start;
- if (offset + sizeof(*test) + test->pdu_len == trace->len) {
- return test->time;
- }
- }
- p--;
- search_len++;
- if (search_len > 8192) {
- break;
- }
- }
- /* searching backwards didn't work out, we'll have to scan the file */
first_record(trace);
while (1) {
if (is_io_event(trace->io))
@@ -373,7 +380,7 @@ static int parse_fio_bank_message(struct trace *trace, u64 *bank_ret, u64 *offse
char *s;
char *next;
char *message;
- struct blk_io_trace *test = trace->io;
+ struct blk_io_trace2 *test = trace->io;
int len = test->pdu_len;
u64 bank;
u64 offset;
@@ -428,7 +435,7 @@ out:
return -1;
}
-static struct dev_info *lookup_dev(struct trace *trace, struct blk_io_trace *io)
+static struct dev_info *lookup_dev(struct trace *trace, struct blk_io_trace2 *io)
{
u32 dev = io->device;
int i;
@@ -481,7 +488,7 @@ static void map_devices(struct trace *trace)
}
}
-static u64 map_io(struct trace *trace, struct blk_io_trace *io)
+static u64 map_io(struct trace *trace, struct blk_io_trace2 *io)
{
struct dev_info *di = lookup_dev(trace, io);
u64 val = trace->io->sector << 9;
@@ -532,7 +539,7 @@ void find_extreme_offsets(struct trace *trace, u64 *min_ret, u64 *max_ret, u64 *
static void check_io_types(struct trace *trace)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
int action = io->action & BLK_TA_MASK;
if (!(io->action & BLK_TC_ACT(BLK_TC_NOTIFY))) {
@@ -850,7 +857,7 @@ struct trace *open_trace(char *filename)
trace->len = st.st_size;
trace->start = p;
trace->cur = p;
- trace->io = (struct blk_io_trace *)p;
+ trace_convert_io(trace);
return trace;
fail_fd:
@@ -901,7 +908,7 @@ static inline int io_event(struct trace *trace)
void add_tput(struct trace *trace, struct graph_line_data *writes_gld,
struct graph_line_data *reads_gld)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
struct graph_line_data *gld;
int action = io->action & BLK_TA_MASK;
int seconds;
@@ -962,7 +969,7 @@ static struct pid_map *get_pid_map(struct trace_file *tf, u32 pid)
void add_io(struct trace *trace, struct trace_file *tf)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
int action = io->action & BLK_TA_MASK;
u64 offset;
int index;
@@ -999,7 +1006,7 @@ void add_io(struct trace *trace, struct trace_file *tf)
void add_pending_io(struct trace *trace, struct graph_line_data *gld)
{
unsigned int seconds;
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
int action = io->action & BLK_TA_MASK;
double avg;
struct pending_io *pio;
@@ -1068,7 +1075,7 @@ account_io:
void add_completed_io(struct trace *trace,
struct graph_line_data *latency_gld)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
int seconds;
int action = io->action & BLK_TA_MASK;
struct pending_io *pio;
@@ -1107,7 +1114,7 @@ void add_completed_io(struct trace *trace,
void add_iop(struct trace *trace, struct graph_line_data *gld)
{
- struct blk_io_trace *io = trace->io;
+ struct blk_io_trace2 *io = trace->io;
int action = io->action & BLK_TA_MASK;
int seconds;
diff --git a/iowatcher/blkparse.h b/iowatcher/blkparse.h
index f82876325ed6..304431e0f0d9 100644
--- a/iowatcher/blkparse.h
+++ b/iowatcher/blkparse.h
@@ -39,7 +39,7 @@ struct trace {
u64 len;
char *start;
char *cur;
- struct blk_io_trace *io;
+ struct blk_io_trace2 *io;
u64 start_timestamp;
struct timespec abs_start_time;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 09/11] iowatcher: natively parse blk_io_trace2
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (7 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 08/11] iowatcher: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:08 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 11/11] blkparse: add option to emit a specific trace protocol version Johannes Thumshirn
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Natively parse 'struct blk_io_trace2' from a blktrace binary.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
iowatcher/blkparse.c | 69 +++++++++++++++++++++++++++++++++++++++++++-
iowatcher/blkparse.h | 1 +
2 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/iowatcher/blkparse.c b/iowatcher/blkparse.c
index ee1c2c511de6..92ee1cc8ec31 100644
--- a/iowatcher/blkparse.c
+++ b/iowatcher/blkparse.c
@@ -288,11 +288,75 @@ static void handle_notify(struct trace *trace)
}
}
+/*
+ * Count how many consecutive well-formed traces the input holds when parsed
+ * with the given trace version.
+ */
+static int count_traces(struct trace *trace, int version)
+{
+ size_t hdr = (version == BLK_IO_TRACE2_VERSION) ?
+ sizeof(struct blk_io_trace2) : sizeof(struct blk_io_trace);
+ char *p = trace->start;
+ char *end = trace->start + trace->len;
+ int n = 0;
+
+ while (n < 16) {
+ struct blk_io_trace *io = (struct blk_io_trace *)p;
+ int pdu_len;
+
+ if (p == end) /* traces tile up to the end */
+ break;
+ if (p + hdr > end)
+ break;
+ if (!CHECK_MAGIC(io))
+ break;
+
+ if (version == BLK_IO_TRACE2_VERSION)
+ pdu_len = ((struct blk_io_trace2 *)p)->pdu_len;
+ else
+ pdu_len = io->pdu_len;
+
+ p += hdr + pdu_len;
+ n++;
+ }
+
+ return n;
+}
+
+/*
+ * A recent blkparse always emits 'struct blk_io_trace2', while an old blkparse
+ * emits 'struct blk_io_trace'. As both share the same magic for version 1
+ * traces, the on-disk layout cannot be told apart by the version alone. Pick
+ * the layout that parses the input cleanly.
+ */
+static int detect_trace_version(struct trace *trace)
+{
+ struct blk_io_trace *io = (struct blk_io_trace *)trace->start;
+
+ if ((io->magic & 0xff) == BLK_IO_TRACE2_VERSION)
+ return BLK_IO_TRACE2_VERSION;
+
+ if (count_traces(trace, BLK_IO_TRACE2_VERSION) >=
+ count_traces(trace, BLK_IO_TRACE_VERSION))
+ return BLK_IO_TRACE2_VERSION;
+
+ return BLK_IO_TRACE_VERSION;
+}
+
static void trace_convert_io(struct trace *trace)
{
struct blk_io_trace *old = (struct blk_io_trace *)trace->cur;
struct blk_io_trace2 *io;
+ if (trace->version == BLK_IO_TRACE2_VERSION) {
+ struct blk_io_trace2 *new = (struct blk_io_trace2 *)trace->cur;
+
+ io = realloc(trace->io, sizeof(*new) + new->pdu_len);
+ memcpy(io, new, sizeof(*new) + new->pdu_len);
+ trace->io = io;
+ return;
+ }
+
io = realloc(trace->io, sizeof(struct blk_io_trace2) + old->pdu_len);
io->magic = old->magic;
@@ -316,10 +380,12 @@ static void trace_convert_io(struct trace *trace)
int next_record(struct trace *trace)
{
+ int hdr = (trace->version == BLK_IO_TRACE2_VERSION) ?
+ sizeof(struct blk_io_trace2) : sizeof(struct blk_io_trace);
int skip = trace->io->pdu_len;
u64 offset;
- trace->cur += sizeof(struct blk_io_trace) + skip;
+ trace->cur += hdr + skip;
offset = trace->cur - trace->start;
if (offset >= trace->len)
return 1;
@@ -857,6 +923,7 @@ struct trace *open_trace(char *filename)
trace->len = st.st_size;
trace->start = p;
trace->cur = p;
+ trace->version = detect_trace_version(trace);
trace_convert_io(trace);
return trace;
diff --git a/iowatcher/blkparse.h b/iowatcher/blkparse.h
index 304431e0f0d9..c59bcf7b5277 100644
--- a/iowatcher/blkparse.h
+++ b/iowatcher/blkparse.h
@@ -39,6 +39,7 @@ struct trace {
u64 len;
char *start;
char *cur;
+ int version;
struct blk_io_trace2 *io;
u64 start_timestamp;
struct timespec abs_start_time;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (8 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 09/11] iowatcher: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:09 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 11/11] blkparse: add option to emit a specific trace protocol version Johannes Thumshirn
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Read the 'magic' portion of the trace first and then parse either 'struct
blk_io_trace' or 'struct blk_io_trace2' depending on the protocol version
of the trace, so btrecord can process both trace file versions.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
btreplay/btrecord.c | 83 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 67 insertions(+), 16 deletions(-)
diff --git a/btreplay/btrecord.c b/btreplay/btrecord.c
index a07ca07aae1f..c1c94567409a 100644
--- a/btreplay/btrecord.c
+++ b/btreplay/btrecord.c
@@ -200,7 +200,7 @@ static inline void fatal(const char *errstring, const int exitval,
* match - Return true if this trace is a proper QUEUE transaction
* @action: Action field from trace
*/
-static inline int match(__u32 action)
+static inline int match(__u64 action)
{
return ((action & 0xffff) == __BLK_TA_QUEUE) &&
(action & BLK_TC_ACT(BLK_TC_QUEUE));
@@ -483,41 +483,92 @@ void handle_args(int argc, char *argv[])
static int next_io(struct ifile_info *iip, struct io_spec *spec)
{
ssize_t ret;
- __u32 action;
+ __u64 action;
__u16 pdu_len;
+ __u32 magic;
+ int version;
struct blk_io_trace t;
+ struct blk_io_trace2 t2;
+ void *p;
again:
- ret = read(iip->ifd, &t, sizeof(t));
+ ret = read(iip->ifd, &magic, sizeof(magic));
if (ret < 0) {
fatal(iip->file_name, ERR_SYSCALL, "Read failed\n");
/*NOTREACHED*/
}
else if (ret == 0)
return 0;
- else if (ret < (ssize_t)sizeof(t)) {
+ else if (ret < (ssize_t)sizeof(magic)) {
fprintf(stderr, "WARNING: Short read on %s (%d)\n",
iip->file_name, (int)ret);
return 0;
}
if (data_is_native == -1)
- check_data_endianness(t.magic);
+ check_data_endianness(magic);
assert(data_is_native >= 0);
- if (data_is_native) {
- spec->time = t.time;
- spec->sector = t.sector;
- spec->bytes = t.bytes;
- action = t.action;
- pdu_len = t.pdu_len;
+
+ version = (data_is_native ? magic : be32_to_cpu(magic)) & 0xff;
+
+ if (version == SUPPORTED_VERSION2) {
+ t2.magic = magic;
+ p = (void *) ((u8 *)&t2 + sizeof(__u32));
+ ret = read(iip->ifd, p, sizeof(t2) - sizeof(__u32));
+ if (ret < 0) {
+ fatal(iip->file_name, ERR_SYSCALL, "Read failed\n");
+ /*NOTREACHED*/
+ }
+ else if (ret < (ssize_t)(sizeof(t2) - sizeof(__u32))) {
+ fprintf(stderr, "WARNING: Short read on %s (%d)\n",
+ iip->file_name, (int)ret);
+ return 0;
+ }
+
+ if (data_is_native) {
+ spec->time = t2.time;
+ spec->sector = t2.sector;
+ spec->bytes = t2.bytes;
+ action = t2.action;
+ pdu_len = t2.pdu_len;
+ }
+ else {
+ spec->time = be64_to_cpu(t2.time);
+ spec->sector = be64_to_cpu(t2.sector);
+ spec->bytes = be32_to_cpu(t2.bytes);
+ action = be64_to_cpu(t2.action);
+ pdu_len = be16_to_cpu(t2.pdu_len);
+ }
}
else {
- spec->time = be64_to_cpu(t.time);
- spec->sector = be64_to_cpu(t.sector);
- spec->bytes = be32_to_cpu(t.bytes);
- action = be32_to_cpu(t.action);
- pdu_len = be16_to_cpu(t.pdu_len);
+ t.magic = magic;
+ p = (void *) ((u8 *)&t + sizeof(__u32));
+ ret = read(iip->ifd, p, sizeof(t) - sizeof(__u32));
+ if (ret < 0) {
+ fatal(iip->file_name, ERR_SYSCALL, "Read failed\n");
+ /*NOTREACHED*/
+ }
+ else if (ret < (ssize_t)(sizeof(t) - sizeof(__u32))) {
+ fprintf(stderr, "WARNING: Short read on %s (%d)\n",
+ iip->file_name, (int)ret);
+ return 0;
+ }
+
+ if (data_is_native) {
+ spec->time = t.time;
+ spec->sector = t.sector;
+ spec->bytes = t.bytes;
+ action = t.action;
+ pdu_len = t.pdu_len;
+ }
+ else {
+ spec->time = be64_to_cpu(t.time);
+ spec->sector = be64_to_cpu(t.sector);
+ spec->bytes = be32_to_cpu(t.bytes);
+ action = be32_to_cpu(t.action);
+ pdu_len = be16_to_cpu(t.pdu_len);
+ }
}
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 11/11] blkparse: add option to emit a specific trace protocol version
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
` (9 preceding siblings ...)
2026-07-16 11:04 ` [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord Johannes Thumshirn
@ 2026-07-16 11:04 ` Johannes Thumshirn
2026-07-16 12:13 ` Damien Le Moal
10 siblings, 1 reply; 23+ messages in thread
From: Johannes Thumshirn @ 2026-07-16 11:04 UTC (permalink / raw)
To: axboe@kernel.dk
Cc: linux-block, Damien Le Moal, Christoph Hellwig,
Chaitanya Kulkarni, linux-btrace, Johannes Thumshirn
Add the '--trace-version=<1|2>' command line option to select the trace
protocol version of the binary output file. Requesting version 1 emits
the legacy 'struct blk_io_trace', while version 2 (the default) emits
'struct blk_io_trace2'.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
blkparse.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------
blktrace.h | 20 +++++++++++++++
doc/blkparse.1 | 7 ++++++
3 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/blkparse.c b/blkparse.c
index 76c775bfe30d..5e4ba331379c 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -119,6 +119,10 @@ static struct per_process_info *ppi_hash_table[PPI_HASH_SIZE];
static struct per_process_info *ppi_list;
static int ppi_list_entries;
+enum {
+ OPT_TRACE_VERSION = 256,
+};
+
static struct option l_opts[] = {
{
.name = "act-mask",
@@ -234,6 +238,12 @@ static struct option l_opts[] = {
.flag = NULL,
.val = 'V'
},
+ {
+ .name = "trace-version",
+ .has_arg = required_argument,
+ .flag = NULL,
+ .val = OPT_TRACE_VERSION
+ },
{
.name = NULL,
}
@@ -306,6 +316,7 @@ int data_is_native = -1;
static FILE *dump_fp;
static char *dump_binary;
+static int dump_trace_version = 2;
static unsigned int t_alloc_cache;
static unsigned int bit_alloc_cache;
@@ -349,14 +360,40 @@ static void io_warn_unless(struct blk_io_trace2 *t, int condition,
static void output_binary(void *buf, int len)
{
- if (dump_binary) {
- size_t n = fwrite(buf, len, 1, dump_fp);
- if (n != 1) {
- perror(dump_binary);
- fclose(dump_fp);
- dump_binary = NULL;
+ if (!dump_binary)
+ return;
+
+ /*
+ * The traces are kept as 'struct blk_io_trace2' internally. When a
+ * version 1 dump is requested, convert them back into the legacy
+ * 'struct blk_io_trace' before writing them out.
+ */
+ if (dump_trace_version == 1) {
+ struct blk_io_trace2 *bit2 = buf;
+ struct blk_io_trace *bit;
+
+ len = sizeof(*bit) + bit2->pdu_len;
+ bit = malloc(len);
+ if (!bit)
+ goto err;
+
+ bit2_to_bit(bit2, bit);
+
+ if (fwrite(bit, len, 1, dump_fp) != 1) {
+ free(bit);
+ goto err;
}
+ free(bit);
+ return;
}
+
+ if (fwrite(buf, len, 1, dump_fp) != 1)
+ goto err;
+ return;
+err:
+ perror(dump_binary);
+ fclose(dump_fp);
+ dump_binary = NULL;
}
static void resize_cpu_info(struct per_dev_info *pdi, int cpu)
@@ -3175,7 +3212,8 @@ static char usage_str[] = "\n\n" \
"[ -w <time> | --stopwatch=<time> ]\n" \
"[ -M | --no-msgs\n" \
"[ -v | --verbose ]\n" \
- "[ -V | --version ]\n\n" \
+ "[ -V | --version ]\n" \
+ "[ --trace-version=<1|2> ]\n\n" \
"\t-a Only trace specified actions. See documentation\n" \
"\t-A Give trace mask as a single value. See documentation\n" \
"\t-b stdin read batching\n" \
@@ -3201,7 +3239,8 @@ static char usage_str[] = "\n\n" \
"\t If 'start' isn't given, blkparse defaults the start time to 0\n" \
"\t-M Do not output messages to binary file\n" \
"\t-v More verbose for marginal errors\n" \
- "\t-V Print program version info\n\n";
+ "\t-V Print program version info\n" \
+ "\t--trace-version Emit a version 1 or 2 (default) binary trace\n\n";
static void usage(char *prog)
{
@@ -3298,6 +3337,17 @@ int main(int argc, char *argv[])
case 'M':
bin_output_msgs = 0;
break;
+ case OPT_TRACE_VERSION: {
+ int ver = atoi(optarg);
+
+ if (ver == 1 || ver == 2)
+ dump_trace_version = ver;
+ else {
+ usage(argv[0]);
+ return 1;
+ }
+ break;
+ }
default:
usage(argv[0]);
return 1;
diff --git a/blktrace.h b/blktrace.h
index ba062372f2c2..370e9218837a 100644
--- a/blktrace.h
+++ b/blktrace.h
@@ -129,6 +129,26 @@ static inline void bit_to_bit2(struct blk_io_trace *old,
old->pdu_len);
}
+static inline void bit2_to_bit(struct blk_io_trace2 *new,
+ struct blk_io_trace *old)
+{
+ old->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
+ old->sequence = new->sequence;
+ old->time = new->time;
+ old->sector = new->sector;
+ old->bytes = new->bytes;
+ old->action = new->action;
+ old->pid = new->pid;
+ old->device = new->device;
+ old->cpu = new->cpu;
+ old->error = new->error;
+ old->pdu_len = new->pdu_len;
+
+ if (old->pdu_len)
+ memcpy(((u8 *) old + sizeof(*old)), ((u8 *)new + sizeof(*new)),
+ new->pdu_len);
+}
+
static inline void bit2_trace_to_cpu(struct blk_io_trace2 *t)
{
if (data_is_native)
diff --git a/doc/blkparse.1 b/doc/blkparse.1
index 93aa44911142..80e7019fe771 100644
--- a/doc/blkparse.1
+++ b/doc/blkparse.1
@@ -151,6 +151,13 @@ Do \fInot\fR produce text output, used for binary (\fB\-d\fR) only
Binary output file
.RE
+\-\-trace\-version=\fI1|2\fR
+.RS
+Selects the trace protocol version of the binary output file (\fB\-d\fR).
+Version 1 emits the legacy \fBstruct blk_io_trace\fR, while version 2 (the
+default) emits \fBstruct blk_io_trace2\fR.
+.RE
+
\-q
.br
\-\-quiet
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 01/11] btt: use blk_io_trace2 internally
2026-07-16 11:04 ` [PATCH 01/11] btt: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:43 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 11:43 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Use 'struct blk_io_trace2' as internal representation for a captured
> blktrace.
>
> This implies the conversion of 'struct blk_io_trace' into 'struct
> blk_io_trace2' when reading the trace from the binary file.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 02/11] btt: natively parse blk_io_trace2
2026-07-16 11:04 ` [PATCH 02/11] btt: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 11:47 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 11:47 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Natively parse 'struct blk_io_trace2' from a blktrace binary.
>
> Detect the layout by parsing the input as both 'struct blk_io_trace' and
s/both/either ?
Otherwise this is unclear as one input cannot have both formats :)
> 'struct blk_io_trace2' and using whichever interprets the trace stream
> cleanly.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Other than the nit above, looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 03/11] blktrace: add option to request a specific trace protocol version
2026-07-16 11:04 ` [PATCH 03/11] blktrace: add option to request a specific trace protocol version Johannes Thumshirn
@ 2026-07-16 11:54 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 11:54 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Add the '--trace-version=<1|2>' command line option to select the trace
> protocol version requested from the kernel. Requesting version 1 forces
> blktrace to use the old BLKTRACESETUP ioctl, while version 2 (the
> default) uses BLKTRACESETUP2.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
> blktrace.c | 30 ++++++++++++++++++++++++++++--
> doc/blktrace.8 | 7 +++++++
> 2 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/blktrace.c b/blktrace.c
> index 72562fdc9d9e..35db26fd4e23 100644
> --- a/blktrace.c
> +++ b/blktrace.c
> @@ -283,6 +283,7 @@ static unsigned long long act_mask = ~0U;
> static int kill_running_trace;
> static int stop_watch;
> static int piped_output;
> +static int v1;
bool ?
Or maybe less confusing/more scalable:
static int trace_ver = 2;
to match the default and the --trace-version option changes that to the
specified value? That simplifies the code below too.
> static void clear_events(struct pollfd *pfd)
> {
> @@ -2244,6 +2257,19 @@ static int handle_args(int argc, char *argv[])
> case 's':
> net_use_sendfile = 0;
> break;
> + case OPT_TRACE_VERSION: {
case OPT_TRACE_VERSION:
trace_ver = atoi(optarg);
if (trace_ver != 1 && trace_ver != 2) {
show_usage(argv[0]);
exit(1);
}
break;
> + int ver = atoi(optarg);
> +
> + if (ver == 1)
> + v1 = 1;
> + else if (ver == 2)
> + v1 = 0;
> + else {
> + show_usage(argv[0]);
> + exit(1);
> + }
> + break;
> + }
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 04/11] blkrawverify: use blk_io_trace2 internally
2026-07-16 11:04 ` [PATCH 04/11] blkrawverify: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 11:55 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 11:55 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Use 'struct blk_io_trace2' as internal representation for a captured
> blktrace.
>
> This implies the conversion of 'struct blk_io_trace' into 'struct
> blk_io_trace2' when reading the trace from the binary file.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 05/11] blkrawverify: natively parse blk_io_trace2
2026-07-16 11:04 ` [PATCH 05/11] blkrawverify: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 12:04 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:04 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Natively parse 'struct blk_io_trace2' from a blktrace binary.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 06/11] blkiomon: use blk_io_trace2 internally
2026-07-16 11:04 ` [PATCH 06/11] blkiomon: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 12:05 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:05 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Use 'struct blk_io_trace2' as internal representation for a captured
> blktrace.
>
> This implies the conversion of 'struct blk_io_trace' into 'struct
> blk_io_trace2' when reading the trace from the binary file.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 07/11] blkiomon: natively parse blk_io_trace2
2026-07-16 11:04 ` [PATCH 07/11] blkiomon: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 12:06 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:06 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Natively parse 'struct blk_io_trace2' from a blktrace binary.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 08/11] iowatcher: use blk_io_trace2 internally
2026-07-16 11:04 ` [PATCH 08/11] iowatcher: use blk_io_trace2 internally Johannes Thumshirn
@ 2026-07-16 12:07 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:07 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Use 'struct blk_io_trace2' as internal representation for a captured
> blktrace.
>
> This implies the conversion of 'struct blk_io_trace' into 'struct
> blk_io_trace2' when reading the trace from the binary file.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 09/11] iowatcher: natively parse blk_io_trace2
2026-07-16 11:04 ` [PATCH 09/11] iowatcher: natively parse blk_io_trace2 Johannes Thumshirn
@ 2026-07-16 12:08 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:08 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Natively parse 'struct blk_io_trace2' from a blktrace binary.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord
2026-07-16 11:04 ` [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord Johannes Thumshirn
@ 2026-07-16 12:09 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:09 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Read the 'magic' portion of the trace first and then parse either 'struct
> blk_io_trace' or 'struct blk_io_trace2' depending on the protocol version
> of the trace, so btrecord can process both trace file versions.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/11] blkparse: add option to emit a specific trace protocol version
2026-07-16 11:04 ` [PATCH 11/11] blkparse: add option to emit a specific trace protocol version Johannes Thumshirn
@ 2026-07-16 12:13 ` Damien Le Moal
0 siblings, 0 replies; 23+ messages in thread
From: Damien Le Moal @ 2026-07-16 12:13 UTC (permalink / raw)
To: Johannes Thumshirn, axboe@kernel.dk
Cc: linux-block, Christoph Hellwig, Chaitanya Kulkarni, linux-btrace
On 7/16/26 20:04, Johannes Thumshirn wrote:
> Add the '--trace-version=<1|2>' command line option to select the trace
> protocol version of the binary output file. Requesting version 1 emits
> the legacy 'struct blk_io_trace', while version 2 (the default) emits
> 'struct blk_io_trace2'.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Looks OK to me, modulo the nit below.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
> @@ -3298,6 +3337,17 @@ int main(int argc, char *argv[])
> case 'M':
> bin_output_msgs = 0;
> break;
> + case OPT_TRACE_VERSION: {
case OPT_TRACE_VERSION:
dump_trace_version = atoi(optarg);
if (dump_trace_version != 1 &&
dump_trace_version != 2) {
usage(argv[0]);
return 1;
}
Is a lot simpler I think.
> + int ver = atoi(optarg);
> +
> + if (ver == 1 || ver == 2)
> + dump_trace_version = ver;
> + else {
> + usage(argv[0]);
> + return 1;
> + }
> + break;
> + }
> default:
> usage(argv[0]);
> return 1;
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-07-16 12:13 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 11:04 [PATCH 00/11] blktrace: parse blk_io_trace2 in btt and iowatcher Johannes Thumshirn
2026-07-16 11:04 ` [PATCH 01/11] btt: use blk_io_trace2 internally Johannes Thumshirn
2026-07-16 11:43 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 02/11] btt: natively parse blk_io_trace2 Johannes Thumshirn
2026-07-16 11:47 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 03/11] blktrace: add option to request a specific trace protocol version Johannes Thumshirn
2026-07-16 11:54 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 04/11] blkrawverify: use blk_io_trace2 internally Johannes Thumshirn
2026-07-16 11:55 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 05/11] blkrawverify: natively parse blk_io_trace2 Johannes Thumshirn
2026-07-16 12:04 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 06/11] blkiomon: use blk_io_trace2 internally Johannes Thumshirn
2026-07-16 12:05 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 07/11] blkiomon: natively parse blk_io_trace2 Johannes Thumshirn
2026-07-16 12:06 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 08/11] iowatcher: use blk_io_trace2 internally Johannes Thumshirn
2026-07-16 12:07 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 09/11] iowatcher: natively parse blk_io_trace2 Johannes Thumshirn
2026-07-16 12:08 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 10/11] btreplay: support blk_io_trace2 in btrecord Johannes Thumshirn
2026-07-16 12:09 ` Damien Le Moal
2026-07-16 11:04 ` [PATCH 11/11] blkparse: add option to emit a specific trace protocol version Johannes Thumshirn
2026-07-16 12:13 ` Damien Le Moal
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.