From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B53C3AEF5A for ; Sat, 3 Oct 2026 12:00:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791028813; cv=none; b=YN12Nep7o7/1VCOuXkQmQk0h4Fa/1hzNTl8NZBh/oufRhM/LuFn9X7VAV3LGrotwW40nV4Vf7XXxIMns2chaoSb0u3YkwG9Ntau5SSGZ0JYofABhoQYwaXxaecFXRiWllwxmo9TG1odS/4MKZbAtA8KvLFRI3Ho1mhANaPD4k80= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791028813; c=relaxed/simple; bh=IvwwLFA/YxoHYhcNqHsqnWvrYLAMS+P069SFvOQcxVQ=; h=Subject:From:To:Date:Message-Id; b=R/W4tgGQRyAPpmHbwh0KDGHpkjBJUMOR51fVOYscFw1IRUAsoXk2mYlg1X+TdPTsoWJiTQdQ9Vr5WhI6iSlpCLA6V95zLO3PyI9WM8BteszdnvheRVmqMSSMsBLRMZ+SrKhl7YtDQGCVTRMP+amgZrC+PPEEIZf9KtGA3Jis19A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=fail smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=oDLE5fb/; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="oDLE5fb/" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Message-Id:Date:To:From:Subject:Sender: Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:In-Reply-To:References; bh=W+Hb7cFedpIViBsQ1I6FrPz+4e/JZilGbyLYcPuhuqs=; b=oDLE5fb/qRKmAg21LRVtOwstb2 iTWPeJw+9mzxHw5CTHMfwk4JwMjmVsH9joNeZnHgvKFPm2KYSBLjF8mW9PcJ936Qp96Kj9uvAckp0 B14IBrlvu/5eOs1RejmpD21j6+qOypGA5uL5Cbu+OrITj6tj1T0GJDZpIQth0QQF6QrKnNPpZ1Fd0 m/6xfN/ydjzCGmTOlg6dLHVIEYQRGQA3c4isSZZmc3xo+ppUWnzhWfuwPZc0H1YVIM1PtWIau+xgk wEjV0wmEv+wWEIBUTbr97D++dzFFXiCm5/oV3YHYLP4EiINZ3iid885VRv3AVm2Wed3ccmrSVFTNC aod8EI+Q==; Received: from [96.43.243.2] (helo=kernel.dk) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1xCyPN-00000006RRH-2A20 for linux-btrace@vger.kernel.org; Sat, 03 Oct 2026 12:00:06 +0000 Received: by kernel.dk (Postfix, from userid 1000) id F07661BC0178; Sat, 3 Oct 2026 06:00:01 -0600 (MDT) Subject: Recent changes (master) From: Jens Axboe To: User-Agent: mail (GNU Mailutils 3.17) Date: Sat, 3 Oct 2026 06:00:01 -0600 Message-Id: <20261003120001.F07661BC0178@kernel.dk> Precedence: bulk X-Mailing-List: linux-btrace@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The following changes since commit 9b24b42ef59d2e8015957db3dd70ffedb7ebcfe8: Update git tree references (2025-12-10 23:53:45 -0700) are available in the Git repository at: git://git.kernel.dk/blktrace.git master for you to fetch changes up to b3015a35bd6332dfead81aa29fed5b8a6567036f: iowatcher/main: remove written only variable (2026-10-02 08:24:58 -0600) ---------------------------------------------------------------- Jens Axboe (1): iowatcher/main: remove written only variable 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 | 64 +++++++++++++++++++--- blkrawverify.c | 69 ++++++++++++++++++------ blktrace.c | 24 ++++++++- 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 +- iowatcher/main.c | 2 - 13 files changed, 543 insertions(+), 117 deletions(-) --- Diff of recent changes: diff --git a/blkiomon.c b/blkiomon.c index 9defa2c..081d1a8 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) @@ -461,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)) @@ -468,26 +473,64 @@ static int blkiomon_do_fifo(void) "blkiomon: could not read trace"); break; } - if (fread(bit, sizeof(*bit), 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"); - break; - } if (data_is_native == -1 && check_data_endianness(magic)) { fprintf(stderr, "blkiomon: endianess problem\n"); break; } - /* endianess */ - bit_trace_to_cpu(bit); + 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"); break; diff --git a/blkparse.c b/blkparse.c index 76c775b..88ef019 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