implement zoned random I/O testing support
authorSteven Noonan <snoonan@amazon.com>
Tue, 31 Jan 2012 12:58:00 +0000 (13:58 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 31 Jan 2012 12:58:00 +0000 (13:58 +0100)
This fixes the limitation that prevents fio from doing random I/O with zones
enabled.

This also adds a 'zonerange' configuration option which may be too ambiguous
and is subject to potential renaming in the future.

When doing random I/O, it is beneficial to be able to specify how large the
addressible space is in the zone, while specifying a different metric for
how much data to read from that zone (i.e., how many samples to take from each
zone). When 'zonerange' is not specified, it defaults to be equal to the
'zonesize' option. When both are specified, 'zonerange' indicates the
size of the zone while 'zonesize' indicates the quantity of data to read from
each zone.

Signed-off-by: Steven Noonan <snoonan@amazon.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fio.h
init.c
io_u.c
options.c

diff --git a/fio.h b/fio.h
index afffb9a..a9286b8 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -168,6 +168,7 @@ struct thread_options {
        unsigned int bw_avg_time;
        unsigned int iops_avg_time;
        unsigned int loops;
        unsigned int bw_avg_time;
        unsigned int iops_avg_time;
        unsigned int loops;
+       unsigned long long zone_range;
        unsigned long long zone_size;
        unsigned long long zone_skip;
        enum fio_memtype mem_type;
        unsigned long long zone_size;
        unsigned long long zone_skip;
        enum fio_memtype mem_type;
diff --git a/init.c b/init.c
index 381bb65..4a3716b 100644 (file)
--- a/init.c
+++ b/init.c
@@ -402,11 +402,18 @@ static int fixup_options(struct thread_data *td)
        }
 
        /*
        }
 
        /*
-        * only really works for sequential io for now, and with 1 file
+        * only really works with 1 file
         */
         */
-       if (o->zone_size && td_random(td) && o->open_files == 1)
+       if (o->zone_size && o->open_files == 1)
                o->zone_size = 0;
 
                o->zone_size = 0;
 
+       /*
+        * If zone_range isn't specified, backward compatibility dictates it
+        * should be made equal to zone_size.
+        */
+       if (o->zone_size && !o->zone_range)
+               o->zone_range = o->zone_size;
+
        /*
         * Reads can do overwrites, we always need to pre-create the file
         */
        /*
         * Reads can do overwrites, we always need to pre-create the file
         */
diff --git a/io_u.c b/io_u.c
index 1aa418c..703d1e8 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -114,6 +114,9 @@ static unsigned long long last_block(struct thread_data *td, struct fio_file *f,
        if (max_size > f->real_file_size)
                max_size = f->real_file_size;
 
        if (max_size > f->real_file_size)
                max_size = f->real_file_size;
 
+       if (td->o.zone_range)
+               max_size = td->o.zone_range;
+
        max_blocks = max_size / (unsigned long long) td->o.ba[ddir];
        if (!max_blocks)
                return 0;
        max_blocks = max_size / (unsigned long long) td->o.ba[ddir];
        if (!max_blocks)
                return 0;
@@ -656,7 +659,8 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
         */
        if (td->zone_bytes >= td->o.zone_size) {
                td->zone_bytes = 0;
         */
        if (td->zone_bytes >= td->o.zone_size) {
                td->zone_bytes = 0;
-               io_u->file->last_pos += td->o.zone_skip;
+               io_u->file->file_offset += td->o.zone_range + td->o.zone_skip;
+               io_u->file->last_pos = io_u->file->file_offset;
                td->io_skip_bytes += td->o.zone_skip;
        }
 
                td->io_skip_bytes += td->o.zone_skip;
        }
 
index f9bd1a4..f62ab6d 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1670,6 +1670,13 @@ static struct fio_option options[FIO_MAX_OPTS] = {
                .name   = "zonesize",
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(zone_size),
                .name   = "zonesize",
                .type   = FIO_OPT_STR_VAL,
                .off1   = td_var_offset(zone_size),
+               .help   = "Amount of data to read per zone",
+               .def    = "0",
+       },
+       {
+               .name   = "zonerange",
+               .type   = FIO_OPT_STR_VAL,
+               .off1   = td_var_offset(zone_range),
                .help   = "Give size of an IO zone",
                .def    = "0",
        },
                .help   = "Give size of an IO zone",
                .def    = "0",
        },