I discovered the race condition when using asynch verify with libaio engine.
The code assumes that because the td->cur_depth value is not 0 that
there is still I/O pending and issues io_getevents when the I/O was
actually being verified by the asynchronous verify thread. This causes
the code to hang.
(Updated by Jens to use a new io_u->flag bitfield instead of adding a new
integer to struct io_u).
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
put_file_log(td, io_u->file);
io_u->file = NULL;
+ if (io_u->flags & IO_U_F_IN_CUR_DEPTH)
+ td->cur_depth--;
flist_del_init(&io_u->list);
flist_add(&io_u->list, &td->io_u_freelist);
- td->cur_depth--;
td_io_u_unlock(td);
td_io_u_free_notify(td);
}
td->io_issues[__io_u->ddir]--;
__io_u->flags &= ~IO_U_F_FLIGHT;
-
+ if (__io_u->flags & IO_U_F_IN_CUR_DEPTH)
+ td->cur_depth--;
flist_del(&__io_u->list);
flist_add_tail(&__io_u->list, &td->io_u_requeues);
- td->cur_depth--;
td_io_u_unlock(td);
*io_u = NULL;
}
flist_del(&io_u->list);
flist_add(&io_u->list, &td->io_u_busylist);
td->cur_depth++;
+ io_u->flags |= IO_U_F_IN_CUR_DEPTH;
}
td_io_u_unlock(td);
#define FIO_IOOPS_VERSION 10
enum {
- IO_U_F_FREE = 1 << 0,
- IO_U_F_FLIGHT = 1 << 1,
- IO_U_F_FREE_DEF = 1 << 2,
+ IO_U_F_FREE = 1 << 0,
+ IO_U_F_FLIGHT = 1 << 1,
+ IO_U_F_FREE_DEF = 1 << 2,
+ IO_U_F_IN_CUR_DEPTH = 1 << 3,
};
/*
io_u->file = NULL;
pthread_mutex_lock(&td->io_u_lock);
+
+ if (io_u->flags & IO_U_F_IN_CUR_DEPTH) {
+ td->cur_depth--;
+ io_u->flags &= ~IO_U_F_IN_CUR_DEPTH;
+ }
flist_del(&io_u->list);
flist_add_tail(&io_u->list, &td->verify_list);
pthread_mutex_unlock(&td->io_u_lock);