Merge branch 'master' of git://github.com/iuliur/fio
authorJens Axboe <axboe@fb.com>
Wed, 6 May 2015 18:36:43 +0000 (12:36 -0600)
committerJens Axboe <axboe@fb.com>
Wed, 6 May 2015 18:36:43 +0000 (12:36 -0600)
Makefile
arch/arch-arm.h
backend.c
blktrace.c
configure
file.h
gettime.c
io_u.c
ioengines.c
lib/libmtd.h
t/lfsr-test.c

index 9b7f27ab735978fc1faa3dda5c2a09556a438ca5..1b312cbda08b2b6784a7b8a75f5978d74d996474 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -243,7 +243,7 @@ ifeq ($(CONFIG_TARGET_OS), SunOS)
 else
        INSTALL = install
 endif
-prefix = /usr/local
+prefix = $(INSTALL_PREFIX)
 bindir = $(prefix)/bin
 
 ifeq ($(CONFIG_TARGET_OS), Darwin)
index bab886e69cf5f4bf14fe9db3c89a5988e4147a56..93268d2fa5b286682c4fcc05e23c777d674bfed2 100644 (file)
@@ -25,7 +25,7 @@
 #define nop             __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t")
 #define read_barrier() __asm__ __volatile__ ("" : : : "memory")
 #define write_barrier()        __asm__ __volatile__ ("" : : : "memory")
-#elif defined(__ARM_ARCH_7A__)
+#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_8A__)
 #define        nop             __asm__ __volatile__ ("nop")
 #define read_barrier() __sync_synchronize()
 #define write_barrier()        __sync_synchronize()
index a0b2c33937ad29afb0c3c7abc04e5d5b9a1cd943..1dcdcf049026db4f1ae33d04284ade793b76d77f 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -363,6 +363,20 @@ static inline int runtime_exceeded(struct thread_data *td, struct timeval *t)
        return 0;
 }
 
+/*
+ * We need to update the runtime consistently in ms, but keep a running
+ * tally of the current elapsed time in microseconds for sub millisecond
+ * updates.
+ */
+static inline void update_runtime(struct thread_data *td,
+                                 unsigned long long *elapsed_us,
+                                 const enum fio_ddir ddir)
+{
+       td->ts.runtime[ddir] -= (elapsed_us[ddir] + 999) / 1000;
+       elapsed_us[ddir] += utime_since_now(&td->start);
+       td->ts.runtime[ddir] += (elapsed_us[ddir] + 999) / 1000;
+}
+
 static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
                               int *retptr)
 {
@@ -1306,7 +1320,7 @@ static void io_workqueue_fn(struct thread_data *td, struct io_u *io_u)
  */
 static void *thread_main(void *data)
 {
-       unsigned long long elapsed;
+       unsigned long long elapsed_us[DDIR_RWDIR_CNT] = { 0, };
        struct thread_data *td = data;
        struct thread_options *o = &td->o;
        pthread_condattr_t attr;
@@ -1544,18 +1558,12 @@ static void *thread_main(void *data)
                check_update_rusage(td);
 
                fio_mutex_down(stat_mutex);
-               if (td_read(td) && td->io_bytes[DDIR_READ]) {
-                       elapsed = mtime_since_now(&td->start);
-                       td->ts.runtime[DDIR_READ] += elapsed;
-               }
-               if (td_write(td) && td->io_bytes[DDIR_WRITE]) {
-                       elapsed = mtime_since_now(&td->start);
-                       td->ts.runtime[DDIR_WRITE] += elapsed;
-               }
-               if (td_trim(td) && td->io_bytes[DDIR_TRIM]) {
-                       elapsed = mtime_since_now(&td->start);
-                       td->ts.runtime[DDIR_TRIM] += elapsed;
-               }
+               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])
+                       update_runtime(td, elapsed_us, DDIR_WRITE);
+               if (td_trim(td) && td->io_bytes[DDIR_TRIM])
+                       update_runtime(td, elapsed_us, DDIR_TRIM);
                fio_gettime(&td->start, NULL);
                fio_mutex_up(stat_mutex);
 
@@ -1579,7 +1587,7 @@ static void *thread_main(void *data)
                check_update_rusage(td);
 
                fio_mutex_down(stat_mutex);
-               td->ts.runtime[DDIR_READ] += mtime_since_now(&td->start);
+               update_runtime(td, elapsed_us, DDIR_READ);
                fio_gettime(&td->start, NULL);
                fio_mutex_up(stat_mutex);
 
index 8ffa9b0e186d49cefa2ad7a21417fe5061079e22..2d4dc1b9fbca3724e47c7285e7fcdab277b82bc3 100644 (file)
@@ -4,6 +4,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
 #include <dirent.h>
 
 #include "flist.h"
@@ -127,17 +129,37 @@ static void trace_add_open_close_event(struct thread_data *td, int fileno, enum
        flist_add_tail(&ipo->list, &td->io_log_list);
 }
 
-static int trace_add_file(struct thread_data *td, __u32 device)
+static int get_dev_blocksize(const char *dev, unsigned int *bs)
 {
-       static unsigned int last_maj, last_min, last_fileno;
+       int fd;
+
+       fd = open(dev, O_RDONLY);
+       if (fd < 0)
+               return 1;
+
+       if (ioctl(fd, BLKSSZGET, bs) < 0) {
+               close(fd);
+               return 1;
+       }
+
+       close(fd);
+       return 0;
+}
+
+static int trace_add_file(struct thread_data *td, __u32 device,
+                         unsigned int *bs)
+{
+       static unsigned int last_maj, last_min, last_fileno, last_bs;
        unsigned int maj = FMAJOR(device);
        unsigned int min = FMINOR(device);
        struct fio_file *f;
-       char dev[256];
        unsigned int i;
+       char dev[256];
 
-       if (last_maj == maj && last_min == min)
+       if (last_maj == maj && last_min == min) {
+               *bs = last_bs;
                return last_fileno;
+       }
 
        last_maj = maj;
        last_min = min;
@@ -145,14 +167,17 @@ static int trace_add_file(struct thread_data *td, __u32 device)
        /*
         * check for this file in our list
         */
-       for_each_file(td, f, i)
+       for_each_file(td, f, i) {
                if (f->major == maj && f->minor == min) {
                        last_fileno = f->fileno;
-                       return last_fileno;
+                       last_bs = f->bs;
+                       goto out;
                }
+       }
 
        strcpy(dev, "/dev");
        if (blktrace_lookup_device(td->o.replay_redirect, dev, maj, min)) {
+               unsigned int this_bs;
                int fileno;
 
                if (td->o.replay_redirect)
@@ -164,13 +189,22 @@ static int trace_add_file(struct thread_data *td, __u32 device)
 
                dprint(FD_BLKTRACE, "add devices %s\n", dev);
                fileno = add_file_exclusive(td, dev);
+
+               if (get_dev_blocksize(dev, &this_bs))
+                       this_bs = 512;
+
                td->o.open_files++;
                td->files[fileno]->major = maj;
                td->files[fileno]->minor = min;
+               td->files[fileno]->bs = this_bs;
                trace_add_open_close_event(td, fileno, FIO_LOG_OPEN_FILE);
+
                last_fileno = fileno;
+               last_bs = this_bs;
        }
 
+out:
+       *bs = last_bs;
        return last_fileno;
 }
 
@@ -179,16 +213,13 @@ static int trace_add_file(struct thread_data *td, __u32 device)
  */
 static void store_ipo(struct thread_data *td, unsigned long long offset,
                      unsigned int bytes, int rw, unsigned long long ttime,
-                     int fileno)
+                     int fileno, unsigned int bs)
 {
        struct io_piece *ipo = malloc(sizeof(*ipo));
 
        init_ipo(ipo);
 
-       /*
-        * the 512 is wrong here, it should be the hardware sector size...
-        */
-       ipo->offset = offset * 512;
+       ipo->offset = offset * bs;
        ipo->len = bytes;
        ipo->delay = ttime / 1000;
        if (rw)
@@ -225,27 +256,25 @@ static void handle_trace_notify(struct blk_io_trace *t)
 static void handle_trace_discard(struct thread_data *td,
                                 struct blk_io_trace *t,
                                 unsigned long long ttime,
-                                unsigned long *ios, unsigned int *bs)
+                                unsigned long *ios, unsigned int *rw_bs)
 {
        struct io_piece *ipo = malloc(sizeof(*ipo));
+       unsigned int bs;
        int fileno;
 
        init_ipo(ipo);
-       fileno = trace_add_file(td, t->device);
+       fileno = trace_add_file(td, t->device, &bs);
 
        ios[DDIR_TRIM]++;
-       if (t->bytes > bs[DDIR_TRIM])
-               bs[DDIR_TRIM] = t->bytes;
+       if (t->bytes > rw_bs[DDIR_TRIM])
+               rw_bs[DDIR_TRIM] = t->bytes;
 
        td->o.size += t->bytes;
 
        memset(ipo, 0, sizeof(*ipo));
        INIT_FLIST_HEAD(&ipo->list);
 
-       /*
-        * the 512 is wrong here, it should be the hardware sector size...
-        */
-       ipo->offset = t->sector * 512;
+       ipo->offset = t->sector * bs;
        ipo->len = t->bytes;
        ipo->delay = ttime / 1000;
        ipo->ddir = DDIR_TRIM;
@@ -259,21 +288,22 @@ static void handle_trace_discard(struct thread_data *td,
 
 static void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t,
                            unsigned long long ttime, unsigned long *ios,
-                           unsigned int *bs)
+                           unsigned int *rw_bs)
 {
+       unsigned int bs;
        int rw;
        int fileno;
 
-       fileno = trace_add_file(td, t->device);
+       fileno = trace_add_file(td, t->device, &bs);
 
        rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
 
-       if (t->bytes > bs[rw])
-               bs[rw] = t->bytes;
+       if (t->bytes > rw_bs[rw])
+               rw_bs[rw] = t->bytes;
 
        ios[rw]++;
        td->o.size += t->bytes;
-       store_ipo(td, t->sector, t->bytes, rw, ttime, fileno);
+       store_ipo(td, t->sector, t->bytes, rw, ttime, fileno, bs);
 }
 
 /*
@@ -503,9 +533,10 @@ int load_blktrace(struct thread_data *td, const char *filename, int need_swap)
 
        /*
         * We need to do direct/raw ios to the device, to avoid getting
-        * read-ahead in our way.
+        * read-ahead in our way. But only do so if the minimum block size
+        * is a multiple of 4k, otherwise we don't know if it's safe to do so.
         */
-       if (!fio_option_is_set(&td->o, odirect))
+       if (!fio_option_is_set(&td->o, odirect) && !(td_min_bs(td) & 4095))
                td->o.odirect = 1;
 
        /*
index 8e496b0f852ab7372fe9254cdbd4cd5ecdd6e61f..3b871efa302acb522ed25f1f51da11fc838b0cb0 100755 (executable)
--- a/configure
+++ b/configure
@@ -135,11 +135,14 @@ show_help="no"
 exit_val=0
 gfio_check="no"
 libhdfs="no"
+prefix=/usr/local
 
 # parse options
 for opt do
   optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
   case "$opt" in
+  --prefix=*) prefix="$optarg"
+  ;;
   --cpu=*) cpu="$optarg"
   ;;
   #  esx is cross compiled and cannot be detect through simple uname calls
@@ -178,6 +181,7 @@ for opt do
 done
 
 if test "$show_help" = "yes" ; then
+  echo "--prefix=              Use this directory as installation prefix"
   echo "--cpu=                 Specify target CPU if auto-detect fails"
   echo "--cc=                  Specify compiler to use"
   echo "--extra-cflags=        Specify extra CFLAGS to pass to compiler"
@@ -716,6 +720,24 @@ EOF
 fi
 echo "CLOCK_MONOTONIC               $clock_monotonic"
 
+##########################################
+# CLOCK_MONOTONIC_RAW probe
+clock_monotonic_raw="no"
+if test "$clock_gettime" = "yes" ; then
+  cat > $TMPC << EOF
+#include <stdio.h>
+#include <time.h>
+int main(int argc, char **argv)
+{
+  return clock_gettime(CLOCK_MONOTONIC_RAW, NULL);
+}
+EOF
+  if compile_prog "" "$LIBS" "clock monotonic"; then
+      clock_monotonic_raw="yes"
+  fi
+fi
+echo "CLOCK_MONOTONIC_RAW           $clock_monotonic_raw"
+
 ##########################################
 # CLOCK_MONOTONIC_PRECISE probe
 clock_monotonic_precise="no"
@@ -1481,6 +1503,9 @@ fi
 if test "$clock_monotonic" = "yes" ; then
   output_sym "CONFIG_CLOCK_MONOTONIC"
 fi
+if test "$clock_monotonic_raw" = "yes" ; then
+  output_sym "CONFIG_CLOCK_MONOTONIC_RAW"
+fi
 if test "$clock_monotonic_precise" = "yes" ; then
   output_sym "CONFIG_CLOCK_MONOTONIC_PRECISE"
 fi
@@ -1612,3 +1637,4 @@ echo "CFLAGS+=$CFLAGS" >> $config_host_mak
 echo "LDFLAGS+=$LDFLAGS" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "BUILD_CFLAGS=$BUILD_CFLAGS $CFLAGS" >> $config_host_mak
+echo "INSTALL_PREFIX=$prefix" >> $config_host_mak
diff --git a/file.h b/file.h
index 22ec742fc1bc47deb22d5552202100b3ea042717..d5595c1671f9e7d0194e463604b353117230ccd8 100644 (file)
--- a/file.h
+++ b/file.h
@@ -78,6 +78,7 @@ struct fio_file {
         */
        unsigned int major, minor;
        int fileno;
+       int bs;
        char *file_name;
 
        /*
index 180aa5f2ed6c3893235e85b8852d5e9a6673affd..ac541113245fb49876ed2afa601894cff3ca776c 100644 (file)
--- a/gettime.c
+++ b/gettime.c
@@ -133,7 +133,9 @@ static void fio_init gtod_init(void)
 #ifdef CONFIG_CLOCK_GETTIME
 static int fill_clock_gettime(struct timespec *ts)
 {
-#ifdef CONFIG_CLOCK_MONOTONIC
+#if defined(CONFIG_CLOCK_MONOTONIC_RAW)
+       return clock_gettime(CLOCK_MONOTONIC_RAW, ts);
+#elif defined(CONFIG_CLOCK_MONOTONIC)
        return clock_gettime(CLOCK_MONOTONIC, ts);
 #else
        return clock_gettime(CLOCK_REALTIME, ts);
diff --git a/io_u.c b/io_u.c
index 50644850463f3e212381ff552f88ce056b5d83b9..d00e6e3fe44a593033670cd5f226fa07395a5698 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1896,8 +1896,10 @@ static struct frand_state *get_buf_state(struct thread_data *td)
 
        if (!td->o.dedupe_percentage)
                return &td->buf_state;
-       else if (td->o.dedupe_percentage == 100)
-               return &td->buf_state_prev;
+       else if (td->o.dedupe_percentage == 100) {
+               frand_copy(&td->buf_state_prev, &td->buf_state);
+               return &td->buf_state;
+       }
 
        r = __rand(&td->dedupe_state);
        v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
@@ -1910,7 +1912,9 @@ static struct frand_state *get_buf_state(struct thread_data *td)
 
 static void save_buf_state(struct thread_data *td, struct frand_state *rs)
 {
-       if (rs == &td->buf_state)
+       if (td->o.dedupe_percentage == 100)
+               frand_copy(rs, &td->buf_state_prev);
+       else if (rs == &td->buf_state)
                frand_copy(&td->buf_state_prev, rs);
 }
 
index b724e0e90e089668ef0a32acd1eb95c7133b4e09..958731dc3bfab9bda2d7765e61d3f31613b02946 100644 (file)
@@ -327,7 +327,8 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
            td->o.odirect) {
 
                log_info("fio: first direct IO errored. File system may not "
-                        "support direct IO, or iomem_align= is bad.\n");
+                        "support direct IO, or iomem_align= is bad. Try "
+                        "setting direct=0.\n");
        }
 
        if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) {
index 33adc145d05fbd54fa2842a54a8fc9771b8d330a..3625de5cea0a2b53019bb7e64042031bd6c15e61 100644 (file)
@@ -78,8 +78,8 @@ struct mtd_dev_info
        int major;
        int minor;
        int type;
-       const char type_str[MTD_TYPE_MAX + 1];
-       const char name[MTD_NAME_MAX + 1];
+       char type_str[MTD_TYPE_MAX + 1];
+       char name[MTD_NAME_MAX + 1];
        long long size;
        int eb_cnt;
        int eb_size;
index 901f1a66bfb30e2184391c1365872d1a646465af..4352b89f3319959ab55c8e90d15e3878717b432e 100644 (file)
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
        if (verify)
                printf("(slower due to verification)");
        printf("\n==============================\n");
-       printf("Elapsed: %lf s\n", total / pow(10,9));
+       printf("Elapsed: %lf s\n", total / pow(10,6));
        printf("Mean:    %lf us\n", mean);
 
        free(v_start);