From 0c6e75175bcaf8d05bfa88aa8caa584fbb848b74 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 22 Feb 2007 11:19:39 +0100 Subject: [PATCH] Track io_u state (free or in-flight) That way we can catch proper use by fio, so we don't get stuck in cleanup_pending_aio() if someone forgot to put_io_u() in an error path. Signed-off-by: Jens Axboe --- fio.c | 15 +++++++++++++-- fio.h | 7 +++++++ io_u.c | 10 ++++++++++ ioengines.c | 4 ++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/fio.c b/fio.c index 9594f805..0ccd5d85 100644 --- a/fio.c +++ b/fio.c @@ -160,9 +160,19 @@ static void cleanup_pending_aio(struct thread_data *td) list_for_each_safe(entry, n, &td->io_u_busylist) { io_u = list_entry(entry, struct io_u, list); - r = td->io_ops->cancel(td, io_u); - if (!r) + /* + * if the io_u isn't in flight, then that generally + * means someone leaked an io_u. complain but fix + * it up, so we don't stall here. + */ + if ((io_u->flags & IO_U_F_FLIGHT) == 0) { + log_err("fio: non-busy IO on busy list\n"); put_io_u(td, io_u); + } else { + r = td->io_ops->cancel(td, io_u); + if (!r) + put_io_u(td, io_u); + } } } @@ -553,6 +563,7 @@ static int init_io_u(struct thread_data *td) fill_rand_buf(io_u, max_bs); io_u->index = i; + io_u->flags = IO_U_F_FREE; list_add(&io_u->list, &td->io_u_freelist); } diff --git a/fio.h b/fio.h index aeb45bf7..c168fe70 100644 --- a/fio.h +++ b/fio.h @@ -76,6 +76,11 @@ struct syslet_req { }; #endif +enum { + IO_U_F_FREE = 1 << 0, + IO_U_F_FLIGHT = 1 << 1, +}; + /* * The io unit */ @@ -124,6 +129,8 @@ struct io_u { unsigned int seen; }; + unsigned int flags; + struct fio_file *file; struct list_head list; diff --git a/io_u.c b/io_u.c index 23a64b04..d30ff4b3 100644 --- a/io_u.c +++ b/io_u.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "fio.h" #include "os.h" @@ -193,6 +194,9 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td) void put_io_u(struct thread_data *td, struct io_u *io_u) { + assert((io_u->flags & IO_U_F_FREE) == 0); + io_u->flags |= IO_U_F_FREE; + io_u->file = NULL; list_del(&io_u->list); list_add(&io_u->list, &td->io_u_freelist); @@ -352,6 +356,9 @@ struct io_u *__get_io_u(struct thread_data *td) } if (io_u) { + assert(io_u->flags & IO_U_F_FREE); + io_u->flags &= ~IO_U_F_FREE; + io_u->error = 0; list_del(&io_u->list); list_add(&io_u->list, &td->io_u_busylist); @@ -441,6 +448,9 @@ static void io_completed(struct thread_data *td, struct io_u *io_u, { unsigned long msec; + assert(io_u->flags & IO_U_F_FLIGHT); + io_u->flags &= ~IO_U_F_FLIGHT; + if (io_u->ddir == DDIR_SYNC) { td->last_was_sync = 1; return; diff --git a/ioengines.c b/ioengines.c index ab5b2245..17044187 100644 --- a/ioengines.c +++ b/ioengines.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "fio.h" #include "os.h" @@ -188,6 +189,9 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) { int ret; + assert((io_u->flags & IO_U_F_FLIGHT) == 0); + io_u->flags |= IO_U_F_FLIGHT; + if (td->io_ops->flags & FIO_SYNCIO) fio_gettime(&io_u->issue_time, NULL); -- 2.25.1