Recent changes (master)
Jens Axboe <[email protected]> Tue, 16 Jun 2026 06:00:01 -0600
| Newsgroups | org.kernel.vger.fio |
|---|---|
| Message-ID | <[email protected]> |
The following changes since commit 19a6a29c6ba25ceb2caa89f1a601cc3a08ab981a:
engines/io_uring: code style tweak (2026-06-13 06:32:38 -0600)
are available in the Git repository at:
git://git.kernel.dk/fio.git master
for you to fetch changes up to fb5b6ae8913be8032beb6cbfe0a4772c74d78cb2:
Merge branch 'pr-speed-up-norandommap-read-bw' of https://github.com/malikoyv/fio (2026-06-15 11:29:22 -0400)
----------------------------------------------------------------
Vincent Fu (1):
Merge branch 'pr-speed-up-norandommap-read-bw' of https://github.com/malikoyv/fio
Yehor Malikov (2):
verify: fix verify starvation with norandommap
iolog: fix io_piece leak on overlapping in-flight writes
io_u.c | 20 ++++++++++++++++----
iolog.c | 1 +
verify.c | 18 +++++++++++++-----
3 files changed, 30 insertions(+), 9 deletions(-)
---
Diff of recent changes:
diff --git a/io_u.c b/io_u.c
index c3327f16..5d704a33 100644
--- a/io_u.c
+++ b/io_u.c
@@ -2167,11 +2167,23 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
/*
* Remove errored entry from the verification list
*/
- if (io_u->error)
+ if (io_u->error) {
unlog_io_piece(td, io_u);
- else {
- atomic_store_release(&io_u->ipo->flags,
- io_u->ipo->flags & ~IP_F_IN_FLIGHT);
+ } else {
+ unsigned int flags = io_u->ipo->flags & ~IP_F_IN_FLIGHT;
+
+ /*
+ * If the io_piece was evicted from the verification
+ * tree due to an overlapping write while in-flight,
+ * it is no longer reachable for verification. Free
+ * it here to avoid a memory leak.
+ */
+ if (!(flags & (IP_F_ONRB | IP_F_ONLIST))) {
+ free(io_u->ipo);
+ io_u->ipo = NULL;
+ } else {
+ atomic_store_release(&io_u->ipo->flags, flags);
+ }
}
}
diff --git a/iolog.c b/iolog.c
index df862ea6..36fcad37 100644
--- a/iolog.c
+++ b/iolog.c
@@ -353,6 +353,7 @@ restart:
ipo->offset, ipo->len);
td->io_hist_len--;
rb_erase(parent, &td->io_hist_tree);
+ __ipo->flags &= ~IP_F_ONRB;
remove_trim_entry(td, __ipo);
if (!(__ipo->flags & IP_F_IN_FLIGHT))
free(__ipo);
diff --git a/verify.c b/verify.c
index d8312815..633a9bb2 100644
--- a/verify.c
+++ b/verify.c
@@ -1425,15 +1425,23 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u)
if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
struct fio_rb_node *n = rb_first(&td->io_hist_tree);
- ipo = rb_entry(n, struct io_piece, rb_node);
-
/*
- * Ensure that the associated IO has completed
+ * Walk the tree to find the first entry whose IO has
+ * completed. The tree is sorted by offset, so the first
+ * entry may still be in-flight while later entries are
+ * already done.
*/
- if (atomic_load_acquire(&ipo->flags) & IP_F_IN_FLIGHT)
+ while (n) {
+ ipo = rb_entry(n, struct io_piece, rb_node);
+ if (!(atomic_load_acquire(&ipo->flags) & IP_F_IN_FLIGHT))
+ break;
+ n = rb_next(n);
+ }
+
+ if (!n)
goto nothing;
- rb_erase(n, &td->io_hist_tree);
+ rb_erase(&ipo->rb_node, &td->io_hist_tree);
assert(ipo->flags & IP_F_ONRB);
ipo->flags &= ~IP_F_ONRB;
} else if (!flist_empty(&td->io_hist_list)) {