From: Bart Van Assche Date: Sat, 13 Jun 2020 18:33:37 +0000 (-0700) Subject: Enable error checking for the mutex that serializes overlapping I/O X-Git-Tag: fio-3.21~15^2~1 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=a38c70a8b84f6f000bd15bec694a4f8b278d46a3;p=fio.git Enable error checking for the mutex that serializes overlapping I/O Since it is nontrivial to verify that pthread_mutex_lock() and unlock calls are paired for the overlap_check mutex, enable runtime verification. The PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP initializer causes pthread_mutex_lock() to fail with EDEADLK if the mutex was already locked and causes pthread_mutex_unlock() to fail with EPERM if the mutex is owned by another thread. Signed-off-by: Bart Van Assche --- diff --git a/backend.c b/backend.c index 0075a733..0e454cdd 100644 --- a/backend.c +++ b/backend.c @@ -66,7 +66,11 @@ unsigned int stat_number = 0; int shm_id = 0; int temp_stall_ts; unsigned long done_secs = 0; +#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +pthread_mutex_t overlap_check = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +#else pthread_mutex_t overlap_check = PTHREAD_MUTEX_INITIALIZER; +#endif #define JOB_START_TIMEOUT (5 * 1000) @@ -1535,7 +1539,7 @@ static void *thread_main(void *data) uint64_t bytes_done[DDIR_RWDIR_CNT]; int deadlock_loop_cnt; bool clear_state; - int ret; + int res, ret; sk_out_assign(sk_out); free(fd); @@ -1860,11 +1864,15 @@ static void *thread_main(void *data) * offload mode so that we don't clean up this job while * another thread is checking its io_u's for overlap */ - if (td_offload_overlap(td)) - pthread_mutex_lock(&overlap_check); + if (td_offload_overlap(td)) { + int res = pthread_mutex_lock(&overlap_check); + assert(res == 0); + } td_set_runstate(td, TD_FINISHING); - if (td_offload_overlap(td)) - pthread_mutex_unlock(&overlap_check); + if (td_offload_overlap(td)) { + res = pthread_mutex_unlock(&overlap_check); + assert(res == 0); + } update_rusage_stat(td); td->ts.total_run_time = mtime_since_now(&td->epoch); diff --git a/ioengines.c b/ioengines.c index c1b430a1..1c5970a4 100644 --- a/ioengines.c +++ b/ioengines.c @@ -313,8 +313,10 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u) * started the overlap check because the IO_U_F_FLIGHT * flag is now set */ - if (td_offload_overlap(td)) - pthread_mutex_unlock(&overlap_check); + if (td_offload_overlap(td)) { + int res = pthread_mutex_unlock(&overlap_check); + assert(res == 0); + } assert(fio_file_open(io_u->file)); diff --git a/rate-submit.c b/rate-submit.c index 3bcb5053..b7b70372 100644 --- a/rate-submit.c +++ b/rate-submit.c @@ -4,6 +4,7 @@ * Copyright (C) 2015 Jens Axboe * */ +#include #include "fio.h" #include "ioengines.h" #include "lib/getrusage.h" @@ -11,7 +12,7 @@ static void check_overlap(struct io_u *io_u) { - int i; + int i, res; struct thread_data *td; /* @@ -26,7 +27,8 @@ static void check_overlap(struct io_u *io_u) * IO_U_F_FLIGHT flag is set so that this io_u can be checked by other * threads as they assess overlap. */ - pthread_mutex_lock(&overlap_check); + res = pthread_mutex_lock(&overlap_check); + assert(res == 0); retry: for_each_td(td, i) { @@ -39,8 +41,10 @@ retry: if (!in_flight_overlap(&td->io_u_all, io_u)) continue; - pthread_mutex_unlock(&overlap_check); - pthread_mutex_lock(&overlap_check); + res = pthread_mutex_unlock(&overlap_check); + assert(res == 0); + res = pthread_mutex_lock(&overlap_check); + assert(res == 0); goto retry; } }