verify: Fix latency log for verify commands.
[fio.git] / backend.c
index f027cf000e96429f0f598b20a2dd33be84f42c62..0f6e4259c4cd5eee6f490bb50e344b95db9c976b 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -418,6 +418,34 @@ static void check_update_rusage(struct thread_data *td)
        }
 }
 
+static int wait_for_completions(struct thread_data *td, struct timeval *time,
+                               uint64_t *bytes_done)
+{
+       const int full = queue_full(td);
+       int min_evts = 0;
+       int ret;
+
+       /*
+        * if the queue is full, we MUST reap at least 1 event
+        */
+       min_evts = min(td->o.iodepth_batch_complete, td->cur_depth);
+       if (full && !min_evts)
+               min_evts = 1;
+
+       if (time && (__should_check_rate(td, DDIR_READ) ||
+           __should_check_rate(td, DDIR_WRITE) ||
+           __should_check_rate(td, DDIR_TRIM)))
+               fio_gettime(time, NULL);
+
+       do {
+               ret = io_u_queued_complete(td, min_evts, bytes_done);
+               if (ret < 0)
+                       break;
+       } while (full && (td->cur_depth > td->o.iodepth_low));
+
+       return ret;
+}
+
 /*
  * The main verify engine. Runs over the writes we previously submitted,
  * reads the blocks back in, and checks the crc/md5 of the data.
@@ -537,6 +565,8 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
                        io_u->end_io = verify_io_u;
 
                ddir = io_u->ddir;
+               if (!td->o.disable_slat)
+                       fio_gettime(&io_u->start_time, NULL);
 
                ret = td_io_queue(td, io_u);
                switch (ret) {
@@ -599,27 +629,9 @@ sync_done:
                 */
 reap:
                full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth);
-               if (full || !td->o.iodepth_batch_complete) {
-                       min_events = min(td->o.iodepth_batch_complete,
-                                        td->cur_depth);
-                       /*
-                        * if the queue is full, we MUST reap at least 1 event
-                        */
-                       if (full && !min_events)
-                               min_events = 1;
+               if (full || !td->o.iodepth_batch_complete)
+                       ret = wait_for_completions(td, NULL, bytes_done);
 
-                       do {
-                               /*
-                                * Reap required number of io units, if any,
-                                * and do the verification on them through
-                                * the callback handler
-                                */
-                               if (io_u_queued_complete(td, min_events, bytes_done) < 0) {
-                                       ret = -1;
-                                       break;
-                               }
-                       } while (full && (td->cur_depth > td->o.iodepth_low));
-               }
                if (ret < 0)
                        break;
        }
@@ -652,7 +664,28 @@ static unsigned int exceeds_number_ios(struct thread_data *td)
        return number_ios >= td->o.number_ios;
 }
 
-static int io_bytes_exceeded(struct thread_data *td)
+static int io_issue_bytes_exceeded(struct thread_data *td)
+{
+       unsigned long long bytes, limit;
+
+       if (td_rw(td))
+               bytes = td->io_issue_bytes[DDIR_READ] + td->io_issue_bytes[DDIR_WRITE];
+       else if (td_write(td))
+               bytes = td->io_issue_bytes[DDIR_WRITE];
+       else if (td_read(td))
+               bytes = td->io_issue_bytes[DDIR_READ];
+       else
+               bytes = td->io_issue_bytes[DDIR_TRIM];
+
+       if (td->o.io_limit)
+               limit = td->o.io_limit;
+       else
+               limit = td->o.size;
+
+       return bytes >= limit || exceeds_number_ios(td);
+}
+
+static int io_complete_bytes_exceeded(struct thread_data *td)
 {
        unsigned long long bytes, limit;
 
@@ -704,10 +737,9 @@ static uint64_t do_io(struct thread_data *td)
                total_bytes += td->o.size;
 
        while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
-               (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td) ||
+               (!flist_empty(&td->trim_list)) || !io_issue_bytes_exceeded(td) ||
                td->o.time_based) {
                struct timeval comp_time;
-               int min_evts = 0;
                struct io_u *io_u;
                int ret2, full;
                enum fio_ddir ddir;
@@ -871,28 +903,8 @@ sync_done:
                 */
 reap:
                full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth);
-               if (full || !td->o.iodepth_batch_complete) {
-                       min_evts = min(td->o.iodepth_batch_complete,
-                                       td->cur_depth);
-                       /*
-                        * if the queue is full, we MUST reap at least 1 event
-                        */
-                       if (full && !min_evts)
-                               min_evts = 1;
-
-                       if (__should_check_rate(td, DDIR_READ) ||
-                           __should_check_rate(td, DDIR_WRITE) ||
-                           __should_check_rate(td, DDIR_TRIM))
-                               fio_gettime(&comp_time, NULL);
-
-                       do {
-                               ret = io_u_queued_complete(td, min_evts, bytes_done);
-                               if (ret < 0)
-                                       break;
-
-                       } while (full && (td->cur_depth > td->o.iodepth_low));
-               }
-
+               if (full || !td->o.iodepth_batch_complete)
+                       ret = wait_for_completions(td, &comp_time, bytes_done);
                if (ret < 0)
                        break;
                if (!ddir_rw_sum(bytes_done) && !(td->io_ops->flags & FIO_NOIO))
@@ -1242,7 +1254,7 @@ static uint64_t do_dry_run(struct thread_data *td)
        td_set_runstate(td, TD_RUNNING);
 
        while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
-               (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td)) {
+               (!flist_empty(&td->trim_list)) || !io_complete_bytes_exceeded(td)) {
                struct io_u *io_u;
                int ret;
 
@@ -2120,7 +2132,8 @@ static void *helper_thread_main(void *data)
                gettimeofday(&tv, NULL);
                ts.tv_sec = tv.tv_sec + sec;
                ts.tv_nsec = (tv.tv_usec * 1000) + nsec;
-               if (ts.tv_nsec > 1000000000ULL) {
+
+               if (ts.tv_nsec >= 1000000000ULL) {
                        ts.tv_nsec -= 1000000000ULL;
                        ts.tv_sec++;
                }