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 afffb9aaf120caf390927ed163533ed20e0aed67..a9286b86729d6231c899ab533b4ab13110513266 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 long long zone_range;
        unsigned long long zone_size;
        unsigned long long zone_skip;
        enum fio_memtype mem_type;
diff --git a/init.c b/init.c
index 381bb654a6c1ca5cf6e833862f670b3743c23708..4a3716bfeb5c058c235e9e529e73c4addef210b2 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;
 
+       /*
+        * 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
         */
diff --git a/io_u.c b/io_u.c
index 1aa418c7554b37babcf2682df1030f390438b428..703d1e85e45ad570715d237bd3dc96fccff6f020 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 (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;
@@ -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;
-               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;
        }
 
index f9bd1a44225cd6f4769952392d0b39a0ce8b0e5d..f62ab6d573cd3369cbeced32edec4a4fe4c666d4 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),
+               .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",
        },