zbd: Avoid async I/O multi-job workload deadlock
[fio.git] / zbd.c
diff --git a/zbd.c b/zbd.c
index 310b173..2da742b 100644 (file)
--- a/zbd.c
+++ b/zbd.c
@@ -1255,7 +1255,21 @@ enum io_u_action zbd_adjust_block(struct thread_data *td, struct io_u *io_u)
 
        zbd_check_swd(f);
 
-       pthread_mutex_lock(&zb->mutex);
+       /*
+        * Lock the io_u target zone. The zone will be unlocked if io_u offset
+        * is changed or when io_u completes and zbd_put_io() executed.
+        * To avoid multiple jobs doing asynchronous I/Os from deadlocking each
+        * other waiting for zone locks when building an io_u batch, first
+        * only trylock the zone. If the zone is already locked by another job,
+        * process the currently queued I/Os so that I/O progress is made and
+        * zones unlocked.
+        */
+       if (pthread_mutex_trylock(&zb->mutex) != 0) {
+               if (!td_ioengine_flagged(td, FIO_SYNCIO))
+                       io_u_quiesce(td);
+               pthread_mutex_lock(&zb->mutex);
+       }
+
        switch (io_u->ddir) {
        case DDIR_READ:
                if (td->runstate == TD_VERIFYING) {