[PATCH] fio: async latency calculation fixes
authorJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 12:35:25 +0000 (14:35 +0200)
committerJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 12:35:25 +0000 (14:35 +0200)
fio.c

diff --git a/fio.c b/fio.c
index ace14b7c655e872f37198673715dea11eb806edf..8ccf5ccca31839c2193d4a61686d8bba2a72d579 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -281,6 +281,11 @@ static unsigned long mtime_since(struct timeval *s, struct timeval *e)
        return sec + usec;
 }
 
+static inline unsigned long msec_now(struct timeval *s)
+{
+       return s->tv_sec * 1000 + s->tv_usec / 1000;
+}
+
 static unsigned long get_next_offset(struct thread_data *td)
 {
        unsigned long b;
@@ -478,7 +483,8 @@ static void aio_put_iocb(struct thread_data *td, struct iocb *iocb)
        td->aio_iocbs_status[offset] = 0;
 }
 
-static struct iocb *aio_get_iocb(struct thread_data *td, char *buffer)
+static struct iocb *aio_get_iocb(struct thread_data *td, char *buffer,
+                                struct timeval *t)
 {
        struct iocb *iocb = NULL;
        int i;
@@ -499,11 +505,15 @@ static struct iocb *aio_get_iocb(struct thread_data *td, char *buffer)
                        io_prep_pread(iocb, td->fd, p, td->bs, off);
                else
                        io_prep_pwrite(iocb, td->fd, p, td->bs, off);
+
+               io_set_callback(iocb, (io_callback_t) msec_now(t));
        }
 
        return iocb;
 }
 
+#define iocb_time(iocb)        ((unsigned long) (iocb)->data)
+
 static void do_async_io(struct thread_data *td)
 {
        struct timeval s, e;
@@ -532,7 +542,7 @@ static void do_async_io(struct thread_data *td)
 
                gettimeofday(&s, NULL);
 
-               iocb = aio_get_iocb(td, buf);
+               iocb = aio_get_iocb(td, buf, &s);
 
                ret = io_submit(*td->aio_ctx, 1, &iocb);
                if (ret < 0) {
@@ -557,6 +567,8 @@ static void do_async_io(struct thread_data *td)
                } else if (!ret)
                        continue;
 
+               gettimeofday(&e, NULL);
+
                for (i = 0; i < ret; i++) {
                        struct io_event *ev = td->aio_events + i;
 
@@ -564,11 +576,23 @@ static void do_async_io(struct thread_data *td)
                        td->aio_cur_depth--;
 
                        iocb = ev->obj;
+
+                       msec = msec_now(&e) - iocb_time(iocb);
+                       add_stat_sample(td, msec);
+
+                       if (msec < td->min_latency)
+                               td->min_latency = msec;
+                       if (msec > td->max_latency)
+                               td->max_latency = msec;
+
                        aio_put_iocb(td, iocb);
                }
 
-               gettimeofday(&e, NULL);
-
+               /*
+                * the rate is batched for now, it should work for batches
+                * of completions except the very first one which may look
+                * a little bursty
+                */
                usec = utime_since(&s, &e);
 
                rate_throttle(td, usec);
@@ -577,14 +601,6 @@ static void do_async_io(struct thread_data *td)
                        td->error = ENODATA;
                        break;
                }
-
-               msec = usec / 1000;
-               add_stat_sample(td, msec);
-
-               if (msec < td->min_latency)
-                       td->min_latency = msec;
-               if (msec > td->max_latency)
-                       td->max_latency = msec;
        }
 
        gettimeofday(&e, NULL);