Add blockalign/ba option
authorJens Axboe <jens.axboe@oracle.com>
Wed, 11 Mar 2009 10:00:13 +0000 (11:00 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 11 Mar 2009 10:00:13 +0000 (11:00 +0100)
Allows the job to specify alignment of the IO specifically, instead
of relying on using blocksize as the offset alignment.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
fio.1
fio.h
init.c
io_u.c
options.c

diff --git a/HOWTO b/HOWTO
index 4e52e6509c18a6efb2350071d15b4899fb0be759..999f7778f37d9d9628f76189609411f7053e77b2 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -327,6 +327,14 @@ bs=int             The block size used for the io units. Defaults to 4k. Values
                can do so by passing an empty read size - bs=,8k will set
                8k for writes and leave the read default value.
 
+blockalign=int
+ba=int         At what boundary to align random IO offsets. Defaults to
+               the same as 'blocksize' the minimum blocksize given.
+               Minimum alignment is typically 512b for using direct IO,
+               though it usually depends on the hardware block size. This
+               option is mutually exclusive with using a random map for
+               files, so it will turn off that option.
+
 blocksize_range=irange
 bsrange=irange Instead of giving a single block size, specify a range
                and fio will mix the issued io block sizes. The issued
diff --git a/fio.1 b/fio.1
index 2eb445578122bb993a5be6569a214e37e7c95743..dd8eda97b1026c502ea03a216c52fea71d944590 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -193,6 +193,12 @@ blocks and 40% 32k blocks.
 If set, any size in \fBblocksize_range\fR may be used.  This typically won't
 work with direct I/O, as that normally requires sector alignment.
 .TP
+.BI blockalign \fR=\fPint[,int] "\fR,\fB ba" \fR=\fPint[,int]
+At what boundary to align random IO offsets. Defaults to the same as
+'blocksize' the minimum blocksize given.  Minimum alignment is typically 512b
+for using direct IO, though it usually depends on the hardware block size.
+This option is mutually exclusive with using a random map for files, so it
+will turn off that option.
 .B zero_buffers
 Initialise buffers with all zeros. Default: fill buffers with random data.
 .TP
diff --git a/fio.h b/fio.h
index b6ffe60b900cfa0f391d9e6c030e3e217f152817..a9e2e3bb6443f9e224da6653e338fd80f3d36241 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -429,6 +429,7 @@ struct thread_options {
        unsigned long long start_offset;
 
        unsigned int bs[2];
+       unsigned int ba[2];
        unsigned int min_bs[2];
        unsigned int max_bs[2];
        struct bssplit *bssplit;
diff --git a/init.c b/init.c
index 4ae3baf0af67b85d88eeaa476f3135011649755c..80d098dd9159a6d926a8c53113946522c10d0084 100644 (file)
--- a/init.c
+++ b/init.c
@@ -273,6 +273,21 @@ static int fixup_options(struct thread_data *td)
 
        o->rw_min_bs = min(o->min_bs[DDIR_READ], o->min_bs[DDIR_WRITE]);
 
+       /*
+        * For random IO, allow blockalign offset other than min_bs.
+        */
+       if (!o->ba[DDIR_READ] || !td_random(td))
+               o->ba[DDIR_READ] = o->min_bs[DDIR_READ];
+       if (!o->ba[DDIR_WRITE] || !td_random(td))
+               o->ba[DDIR_WRITE] = o->min_bs[DDIR_WRITE];
+
+       if ((o->ba[DDIR_READ] != o->min_bs[DDIR_READ] ||
+           o->ba[DDIR_WRITE] != o->min_bs[DDIR_WRITE]) &&
+           !td->o.norandommap) {
+               log_err("fio: Any use of blockalign= turns off randommap\n");
+               td->o.norandommap = 1;
+       }
+
        if (!o->file_size_high)
                o->file_size_high = o->file_size_low;
 
diff --git a/io_u.c b/io_u.c
index 27014c8aad503b4cb8ed7eba374a954b6b7c6a2d..476658edfc9ee48baa2bab76846135dbcbc9b127 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -95,7 +95,7 @@ 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;
 
-       max_blocks = max_size / (unsigned long long) td->o.min_bs[ddir];
+       max_blocks = max_size / (unsigned long long) td->o.ba[ddir];
        if (!max_blocks)
                return 0;
 
@@ -212,7 +212,7 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
                        b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
        }
 
-       io_u->offset = b * td->o.min_bs[ddir];
+       io_u->offset = b * td->o.ba[ddir];
        if (io_u->offset >= f->io_size) {
                dprint(FD_IO, "get_next_offset: offset %llu >= io_size %llu\n",
                                        io_u->offset, f->io_size);
index 73815bb0d1d4a6d74d9984b54b98b37ec3b55921..9700110983cc6d04ff4ebc4e356fab10ef2e2cee 100644 (file)
--- a/options.c
+++ b/options.c
@@ -792,6 +792,16 @@ static struct fio_option options[] = {
                .def    = "4k",
                .parent = "rw",
        },
+       {
+               .name   = "ba",
+               .alias  = "blockalign",
+               .type   = FIO_OPT_STR_VAL_INT,
+               .off1   = td_var_offset(ba[DDIR_READ]),
+               .off2   = td_var_offset(ba[DDIR_WRITE]),
+               .minval = 1,
+               .help   = "IO block offset alignment",
+               .parent = "rw",
+       },
        {
                .name   = "bsrange",
                .alias  = "blocksize_range",