backend: if we can't grab stat_mutex, report a deadlock error and exit
[fio.git] / backend.c
index b43486dc7b2ff016b6d76d281dc479692e90b231..093b6a3a290e25e406fa15026d1cca055f6e0816 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1471,6 +1471,7 @@ static void *thread_main(void *data)
        struct thread_data *td = fd->td;
        struct thread_options *o = &td->o;
        struct sk_out *sk_out = fd->sk_out;
+       int deadlock_loop_cnt;
        int clear_state;
        int ret;
 
@@ -1675,7 +1676,7 @@ static void *thread_main(void *data)
        if (rate_submit_init(td, sk_out))
                goto err;
 
-       fio_gettime(&td->epoch, NULL);
+       set_epoch_time(td, o->log_unix_epoch);
        fio_getrusage(&td->ru_start);
        memcpy(&td->bw_sample_time, &td->epoch, sizeof(td->epoch));
        memcpy(&td->iops_sample_time, &td->epoch, sizeof(td->epoch));
@@ -1731,9 +1732,19 @@ static void *thread_main(void *data)
                 * the rusage_sem, which would never get upped because
                 * this thread is waiting for the stat mutex.
                 */
-               check_update_rusage(td);
+               deadlock_loop_cnt = 0;
+               do {
+                       check_update_rusage(td);
+                       if (!fio_mutex_down_trylock(stat_mutex))
+                               break;
+                       usleep(1000);
+                       if (deadlock_loop_cnt++ > 5000) {
+                               log_err("fio seems to be stuck grabbing stat_mutex, forcibly exiting\n");
+                               td->error = EDEADLOCK;
+                               goto err;
+                       }
+               } while (1);
 
-               fio_mutex_down(stat_mutex);
                if (td_read(td) && td->io_bytes[DDIR_READ])
                        update_runtime(td, elapsed_us, DDIR_READ);
                if (td_write(td) && td->io_bytes[DDIR_WRITE])