log: fix for crash with rate IO and logging
[fio.git] / backend.c
index 093b6a3a290e25e406fa15026d1cca055f6e0816..ac71521e94fc4420714823aab73c45a924e0432d 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -441,11 +441,8 @@ static int wait_for_completions(struct thread_data *td, struct timeval *time)
        int min_evts = 0;
        int ret;
 
-       if (td->flags & TD_F_REGROW_LOGS) {
-               ret = io_u_quiesce(td);
-               regrow_logs(td);
-               return ret;
-       }
+       if (td->flags & TD_F_REGROW_LOGS)
+               return io_u_quiesce(td);
 
        /*
         * if the queue is full, we MUST reap at least 1 event
@@ -771,18 +768,18 @@ static bool exceeds_number_ios(struct thread_data *td)
        return number_ios >= (td->o.number_ios * td->loops);
 }
 
-static bool io_issue_bytes_exceeded(struct thread_data *td)
+static bool io_bytes_exceeded(struct thread_data *td, uint64_t *this_bytes)
 {
        unsigned long long bytes, limit;
 
        if (td_rw(td))
-               bytes = td->io_issue_bytes[DDIR_READ] + td->io_issue_bytes[DDIR_WRITE];
+               bytes = this_bytes[DDIR_READ] + this_bytes[DDIR_WRITE];
        else if (td_write(td))
-               bytes = td->io_issue_bytes[DDIR_WRITE];
+               bytes = this_bytes[DDIR_WRITE];
        else if (td_read(td))
-               bytes = td->io_issue_bytes[DDIR_READ];
+               bytes = this_bytes[DDIR_READ];
        else
-               bytes = td->io_issue_bytes[DDIR_TRIM];
+               bytes = this_bytes[DDIR_TRIM];
 
        if (td->o.io_limit)
                limit = td->o.io_limit;
@@ -793,26 +790,14 @@ static bool io_issue_bytes_exceeded(struct thread_data *td)
        return bytes >= limit || exceeds_number_ios(td);
 }
 
-static bool io_complete_bytes_exceeded(struct thread_data *td)
+static bool io_issue_bytes_exceeded(struct thread_data *td)
 {
-       unsigned long long bytes, limit;
-
-       if (td_rw(td))
-               bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE];
-       else if (td_write(td))
-               bytes = td->this_io_bytes[DDIR_WRITE];
-       else if (td_read(td))
-               bytes = td->this_io_bytes[DDIR_READ];
-       else
-               bytes = td->this_io_bytes[DDIR_TRIM];
-
-       if (td->o.io_limit)
-               limit = td->o.io_limit;
-       else
-               limit = td->o.size;
+       return io_bytes_exceeded(td, td->io_issue_bytes);
+}
 
-       limit *= td->loops;
-       return bytes >= limit || exceeds_number_ios(td);
+static bool io_complete_bytes_exceeded(struct thread_data *td)
+{
+       return io_bytes_exceeded(td, td->this_io_bytes);
 }
 
 /*
@@ -1723,6 +1708,14 @@ static void *thread_main(void *data)
                        }
                }
 
+               /*
+                * If we took too long to shut down, the main thread could
+                * already consider us reaped/exited. If that happens, break
+                * out and clean up.
+                */
+               if (td->runstate >= TD_EXITED)
+                       break;
+
                clear_state = 1;
 
                /*
@@ -1740,7 +1733,7 @@ static void *thread_main(void *data)
                        usleep(1000);
                        if (deadlock_loop_cnt++ > 5000) {
                                log_err("fio seems to be stuck grabbing stat_mutex, forcibly exiting\n");
-                               td->error = EDEADLOCK;
+                               td->error = EDEADLK;
                                goto err;
                        }
                } while (1);
@@ -1868,8 +1861,8 @@ static void dump_td_info(struct thread_data *td)
 /*
  * Run over the job map and reap the threads that have exited, if any.
  */
-static void reap_threads(unsigned int *nr_running, unsigned int *t_rate,
-                        unsigned int *m_rate)
+static void reap_threads(unsigned int *nr_running, uint64_t *t_rate,
+                        uint64_t *m_rate)
 {
        struct thread_data *td;
        unsigned int cputhreads, realthreads, pending;
@@ -2107,7 +2100,8 @@ static bool waitee_running(struct thread_data *me)
 static void run_threads(struct sk_out *sk_out)
 {
        struct thread_data *td;
-       unsigned int i, todo, nr_running, m_rate, t_rate, nr_started;
+       unsigned int i, todo, nr_running, nr_started;
+       uint64_t m_rate, t_rate;
        uint64_t spent;
 
        if (fio_gtod_offload && fio_start_gtod_thread())