From 439097d89cf841708ecfc05397a680495062c0bf Mon Sep 17 00:00:00 2001 From: rorychen Date: Thu, 13 Aug 2026 23:48:42 +0800 Subject: [PATCH] fio replay: replay I/O from __BLK_TA_ISSUE action instead of __BLK_TA_QUEUE Use __BLK_TA_ISSUE instead of __BLK_TA_QUEUE action events for fio replay. IO requests may be merged after __BLK_TA_QUEUE, causing replayed I/O to differ from the actual I/O issued to the driver. Replaying from __BLK_TA_ISSUE more accurately reflects device traffic. This change also fixes a bug where write requests with the BLK_TC_FLUSH category would be lost when replaying from __BLK_TA_QUEUE action. Signed-off-by: Rory Chen --- blktrace.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/blktrace.c b/blktrace.c index 71d211227a..9a18214f0e 100644 --- a/blktrace.c +++ b/blktrace.c @@ -317,9 +317,27 @@ static bool queue_trace(struct thread_data *td, struct blk_io_trace *t, unsigned long long *last_ttime = &td->io_log_last_ttime; unsigned long long delay = 0; - if ((t->action & 0xffff) != __BLK_TA_QUEUE) + /* Ignore PC requests */ + if ( t->action & BLK_TC_ACT(BLK_TC_PC)) return false; + /* Replay FLUSH/DISCARD/NOTIFY from Q(QUEUE) action, + * replay all other commands from D(ISSUE) action. + */ + + if (t->action & (BLK_TC_ACT(BLK_TC_NOTIFY) | + BLK_TC_ACT(BLK_TC_DISCARD) | + BLK_TC_ACT(BLK_TC_FLUSH))) { + + if ( (t->action & 0xffff) != __BLK_TA_QUEUE) + return false; + /* special cmd processing */ + } else { + if ( (t->action & 0xffff) != __BLK_TA_ISSUE) + return false; + /* normal IO processing */ + } + if (!(t->action & BLK_TC_ACT(BLK_TC_NOTIFY))) { delay = delay_since_ttime(td, t->time); *last_ttime = t->time; @@ -332,6 +350,7 @@ static bool queue_trace(struct thread_data *td, struct blk_io_trace *t, else if (t->action & BLK_TC_ACT(BLK_TC_DISCARD)) return handle_trace_discard(td, t, delay, ios, bs, cache); else if (t->action & BLK_TC_ACT(BLK_TC_FLUSH)) + /*Replay Flush with F category in Q(QUEUE) action*/ return handle_trace_flush(td, t, delay, ios, cache); else return handle_trace_fs(td, t, delay, ios, bs, cache); @@ -378,15 +397,6 @@ static void depth_inc(struct blk_io_trace *t, int *depth) depth[ddir]++; } -static void depth_dec(struct blk_io_trace *t, int *depth) -{ - enum fio_ddir ddir; - - ddir = t_get_ddir(t); - if (ddir != DDIR_INVAL) - depth[ddir]--; -} - static void depth_end(struct blk_io_trace *t, int *this_depth, int *depth) { enum fio_ddir ddir = DDIR_INVAL; @@ -496,11 +506,11 @@ bool read_blktrace(struct thread_data* td) goto err; } if ((t.action & BLK_TC_ACT(BLK_TC_NOTIFY)) == 0) { - if ((t.action & 0xffff) == __BLK_TA_QUEUE) + + /* Increase queue depth at the action of __BLK_TA_ISSUE "D" instead of __BLK_TA_QUEUE as the queued IO + * may be merged to send to the driver.*/ + if ( ((t.action & 0xffff) == __BLK_TA_ISSUE) && ( (t.action & BLK_TC_ACT(BLK_TC_READ)) || (t.action & BLK_TC_ACT(BLK_TC_WRITE)) ) ) depth_inc(&t, this_depth); - else if (((t.action & 0xffff) == __BLK_TA_BACKMERGE) || - ((t.action & 0xffff) == __BLK_TA_FRONTMERGE)) - depth_dec(&t, this_depth); else if ((t.action & 0xffff) == __BLK_TA_COMPLETE) depth_end(&t, this_depth, depth);