blktrace replay: delay support
authorJens Axboe <jens.axboe@oracle.com>
Tue, 15 May 2007 12:29:58 +0000 (14:29 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 15 May 2007 12:29:58 +0000 (14:29 +0200)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
blktrace.c
fio.h
ioengines.c
log.c

index 1669fe556bc3324d2b40567e0afdab0f0e359667..5793773a10837799dea5644cef66277ffaf85c7e 100644 (file)
@@ -110,9 +110,10 @@ static void handle_trace(struct thread_data *td, struct blk_io_trace *t,
  */
 int load_blktrace(struct thread_data *td, const char *filename)
 {
-       unsigned long long ttime;
+       unsigned long long ttime, delay;
        struct blk_io_trace t;
        unsigned long ios[2];
+       unsigned int cpu;
        int fd;
 
        fd = open(filename, O_RDONLY);
@@ -125,6 +126,7 @@ int load_blktrace(struct thread_data *td, const char *filename)
 
        ios[0] = ios[1] = 0;
        ttime = 0;
+       cpu = 0;
        do {
                /*
                 * Once this is working fully, I'll add a layer between
@@ -157,10 +159,16 @@ int load_blktrace(struct thread_data *td, const char *filename)
                        td_verror(td, ret, "blktrace lseek");
                        goto err;
                }
-               if (!ttime)
+               if (!ttime) {
                        ttime = t.time;
-               handle_trace(td, &t, t.time - ttime, ios);
+                       cpu = t.cpu;
+               }
+               delay = 0;
+               if (cpu == t.cpu)
+                       delay = t.time - ttime;
+               handle_trace(td, &t, delay, ios);
                ttime = t.time;
+               cpu = t.cpu;
        } while (1);
 
        close(fd);
diff --git a/fio.h b/fio.h
index 870b6704a7852a938d47830e85f5753165d45de1..fa0edb1ed02938899776f397aa97b446ad7052e1 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -522,6 +522,7 @@ struct thread_data {
        struct timeval start;   /* start of this loop */
        struct timeval epoch;   /* time job was started */
        struct timeval rw_end[2];
+       struct timeval last_issue;
        unsigned int rw_end_set[2];
 
        /*
index 28cdfd49b00cd24915f39c7b117e3d2e96e9e31f..feb986a844bba2342c5844094bacc89f6ed26821 100644 (file)
@@ -192,6 +192,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
 
        if (td->io_ops->flags & FIO_SYNCIO) {
                fio_gettime(&io_u->issue_time, NULL);
+               memcpy(&td->last_issue, &io_u->issue_time, sizeof(struct timeval));
 
                /*
                 * for a sync engine, set the timeout upfront
@@ -220,6 +221,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
 
        if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
                fio_gettime(&io_u->issue_time, NULL);
+               memcpy(&td->last_issue, &io_u->issue_time, sizeof(struct timeval));
 
                /*
                 * async engine, set the timeout here
diff --git a/log.c b/log.c
index c0e9d4ae61dc8b6b5f7d1890991745979872a7f0..5ed30eb6f103efb8ed6150d04a807a9dc018ef63 100644 (file)
--- a/log.c
+++ b/log.c
@@ -8,6 +8,24 @@ void write_iolog_put(struct thread_data *td, struct io_u *io_u)
        fprintf(td->iolog_f, "%u,%llu,%lu\n", io_u->ddir, io_u->offset, io_u->buflen);
 }
 
+static void iolog_delay(struct thread_data *td, unsigned long delay)
+{
+       unsigned long usec = utime_since_now(&td->last_issue);
+
+       if (delay < usec)
+               return;
+
+       delay -= usec;
+
+       /*
+        * less than 100 usec delay, just regard it as noise
+        */
+       if (delay < 100)
+               return;
+
+       usec_sleep(td, delay);
+}
+
 int read_iolog_get(struct thread_data *td, struct io_u *io_u)
 {
        struct io_piece *ipo;
@@ -19,6 +37,10 @@ int read_iolog_get(struct thread_data *td, struct io_u *io_u)
                io_u->buflen = ipo->len;
                io_u->ddir = ipo->ddir;
                io_u->file = ipo->file;
+
+               if (ipo->delay)
+                       iolog_delay(td, ipo->delay);
+
                /*
                 * work around, this needs a format change to work for > 1 file
                 */