Assertion in ioengines.c::td_io_queue() fails for pthread_mutex_unlock()
on overlap_check mutex when serialize_overlap=1, io_submit_mode=offload,
and verify=<any> are used together.
backend.c::fio_io_sync() invokes td_io_queue(), which expects the caller
to have ownership of the overlap_check mutex when serialize_overlap
and offloading are configured, as part of the overlap-check interlock
with IO_U_F_FLIGHT. The mutex is not acquired for this path because it's
not an I/O requiring an overlap check.
The fix is to refine the conditional that triggers td_io_queue() to
release the overlap_check mutex. Rather than using broad config options,
the conditional now uses a new io_u flag named IO_U_F_OVERLAP_LOCK, which
is only set for the offload worker thread path that acquires the mutex.
Link: https://github.com/axboe/fio/issues/1520
Signed-off-by: Adam Horshack (horshack@live.com)
IO_U_F_TRIMMED = 1 << 5,
IO_U_F_BARRIER = 1 << 6,
IO_U_F_VER_LIST = 1 << 7,
IO_U_F_TRIMMED = 1 << 5,
IO_U_F_BARRIER = 1 << 6,
IO_U_F_VER_LIST = 1 << 7,
+ IO_U_F_OVERLAP_LOCK = 1 << 8,
* started the overlap check because the IO_U_F_FLIGHT
* flag is now set
*/
* started the overlap check because the IO_U_F_FLIGHT
* flag is now set
*/
- if (td_offload_overlap(td)) {
+ if (io_u->flags & IO_U_F_OVERLAP_LOCK) {
int res = pthread_mutex_unlock(&overlap_check);
assert(res == 0);
int res = pthread_mutex_unlock(&overlap_check);
assert(res == 0);
+ io_u_clear(td, io_u, IO_U_F_OVERLAP_LOCK);
}
assert(fio_file_open(io_u->file));
}
assert(fio_file_open(io_u->file));
assert(res == 0);
goto retry;
}
assert(res == 0);
goto retry;
}
+ io_u_set(td, io_u, IO_U_F_OVERLAP_LOCK);
}
static int io_workqueue_fn(struct submit_worker *sw,
}
static int io_workqueue_fn(struct submit_worker *sw,