From: Jens Axboe <axboe@kernel.dk>
To: "Neto, Antonio Jose Rodrigues" <Antonio.Jose.Rodrigues.Neto@netapp.com>
Cc: "fio@vger.kernel.org" <fio@vger.kernel.org>
Subject: Re: Helping to model this workload
Date: Thu, 25 Jul 2013 12:42:44 -0600 [thread overview]
Message-ID: <20130725184244.GI29296@kernel.dk> (raw)
In-Reply-To: <CE16E6E8.12D27%Antonio.Jose.Rodrigues.Neto@netapp.com>
On Thu, Jul 25 2013, Neto, Antonio Jose Rodrigues wrote:
> >BTW, if you use filename= twice like you do above, only the last one
> >will be effective.
>
> And if I do this? file_service_type=random
Doesn't matter. You have to give all files in one filename= statement,
there are not additive.
The below should add bs_is_seq_rand support. If you set that to 1, then:
bs=4k,64k
will not be reads 4k and writes 64k, it will be sequential 4k and random
64k instead. Totally untested...
diff --git a/cconv.c b/cconv.c
index 9de4e25..8e7c69e 100644
--- a/cconv.c
+++ b/cconv.c
@@ -123,6 +123,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
o->softrandommap = le32_to_cpu(top->softrandommap);
o->bs_unaligned = le32_to_cpu(top->bs_unaligned);
o->fsync_on_close = le32_to_cpu(top->fsync_on_close);
+ o->bs_is_seq_rand = le32_to_cpu(top->bs_is_seq_rand);
o->random_distribution = le32_to_cpu(top->random_distribution);
o->zipf_theta.u.f = fio_uint64_to_double(le64_to_cpu(top->zipf_theta.u.i));
o->pareto_h.u.f = fio_uint64_to_double(le64_to_cpu(top->pareto_h.u.i));
@@ -281,6 +282,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
top->softrandommap = cpu_to_le32(o->softrandommap);
top->bs_unaligned = cpu_to_le32(o->bs_unaligned);
top->fsync_on_close = cpu_to_le32(o->fsync_on_close);
+ top->bs_is_seq_rand = cpu_to_le32(o->bs_is_seq_rand);
top->random_distribution = cpu_to_le32(o->random_distribution);
top->zipf_theta.u.i = __cpu_to_le64(fio_double_to_uint64(o->zipf_theta.u.f));
top->pareto_h.u.i = __cpu_to_le64(fio_double_to_uint64(o->pareto_h.u.f));
diff --git a/io_u.c b/io_u.c
index 8401719..6537c90 100644
--- a/io_u.c
+++ b/io_u.c
@@ -293,7 +293,8 @@ static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
}
static int get_next_block(struct thread_data *td, struct io_u *io_u,
- enum fio_ddir ddir, int rw_seq)
+ enum fio_ddir ddir, int rw_seq,
+ unsigned int *is_random)
{
struct fio_file *f = io_u->file;
uint64_t b, offset;
@@ -305,23 +306,30 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
if (rw_seq) {
if (td_random(td)) {
- if (should_do_random(td, ddir))
+ if (should_do_random(td, ddir)) {
ret = get_next_rand_block(td, f, ddir, &b);
- else {
+ *is_random = 1;
+ } else {
+ *is_random = 0;
io_u->flags |= IO_U_F_BUSY_OK;
ret = get_next_seq_offset(td, f, ddir, &offset);
if (ret)
ret = get_next_rand_block(td, f, ddir, &b);
}
- } else
+ } else {
+ *is_random = 0;
ret = get_next_seq_offset(td, f, ddir, &offset);
+ }
} else {
io_u->flags |= IO_U_F_BUSY_OK;
+ *is_random = 0;
if (td->o.rw_seq == RW_SEQ_SEQ) {
ret = get_next_seq_offset(td, f, ddir, &offset);
- if (ret)
+ if (ret) {
ret = get_next_rand_block(td, f, ddir, &b);
+ *is_random = 0;
+ }
} else if (td->o.rw_seq == RW_SEQ_IDENT) {
if (f->last_start != -1ULL)
offset = f->last_start - f->file_offset;
@@ -353,7 +361,8 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
* until we find a free one. For sequential io, just return the end of
* the last io issued.
*/
-static int __get_next_offset(struct thread_data *td, struct io_u *io_u)
+static int __get_next_offset(struct thread_data *td, struct io_u *io_u,
+ unsigned int *is_random)
{
struct fio_file *f = io_u->file;
enum fio_ddir ddir = io_u->ddir;
@@ -366,7 +375,7 @@ static int __get_next_offset(struct thread_data *td, struct io_u *io_u)
td->ddir_seq_nr = td->o.ddir_seq_nr;
}
- if (get_next_block(td, io_u, ddir, rw_seq_hit))
+ if (get_next_block(td, io_u, ddir, rw_seq_hit, is_random))
return 1;
if (io_u->offset >= f->io_size) {
@@ -387,16 +396,17 @@ static int __get_next_offset(struct thread_data *td, struct io_u *io_u)
return 0;
}
-static int get_next_offset(struct thread_data *td, struct io_u *io_u)
+static int get_next_offset(struct thread_data *td, struct io_u *io_u,
+ unsigned int *is_random)
{
if (td->flags & TD_F_PROFILE_OPS) {
struct prof_io_ops *ops = &td->prof_io_ops;
if (ops->fill_io_u_off)
- return ops->fill_io_u_off(td, io_u);
+ return ops->fill_io_u_off(td, io_u, is_random);
}
- return __get_next_offset(td, io_u);
+ return __get_next_offset(td, io_u, is_random);
}
static inline int io_u_fits(struct thread_data *td, struct io_u *io_u,
@@ -407,14 +417,20 @@ static inline int io_u_fits(struct thread_data *td, struct io_u *io_u,
return io_u->offset + buflen <= f->io_size + get_start_offset(td);
}
-static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
+static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
+ unsigned int is_random)
{
- const int ddir = io_u->ddir;
+ int ddir = io_u->ddir;
unsigned int buflen = 0;
unsigned int minbs, maxbs;
unsigned long r, rand_max;
- assert(ddir_rw(ddir));
+ assert(ddir_rw(io_u->ddir));
+
+ if (td->o.bs_is_seq_rand)
+ ddir = is_random ? DDIR_WRITE: DDIR_READ;
+ else
+ ddir = io_u->ddir;
minbs = td->o.min_bs[ddir];
maxbs = td->o.max_bs[ddir];
@@ -471,16 +487,17 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
return buflen;
}
-static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
+static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u,
+ unsigned int is_random)
{
if (td->flags & TD_F_PROFILE_OPS) {
struct prof_io_ops *ops = &td->prof_io_ops;
if (ops->fill_io_u_size)
- return ops->fill_io_u_size(td, io_u);
+ return ops->fill_io_u_size(td, io_u, is_random);
}
- return __get_next_buflen(td, io_u);
+ return __get_next_buflen(td, io_u, is_random);
}
static void set_rwmix_bytes(struct thread_data *td)
@@ -715,6 +732,8 @@ void requeue_io_u(struct thread_data *td, struct io_u **io_u)
static int fill_io_u(struct thread_data *td, struct io_u *io_u)
{
+ unsigned int is_random;
+
if (td->io_ops->flags & FIO_NOIO)
goto out;
@@ -740,12 +759,12 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
* No log, let the seq/rand engine retrieve the next buflen and
* position.
*/
- if (get_next_offset(td, io_u)) {
+ if (get_next_offset(td, io_u, &is_random)) {
dprint(FD_IO, "io_u %p, failed getting offset\n", io_u);
return 1;
}
- io_u->buflen = get_next_buflen(td, io_u);
+ io_u->buflen = get_next_buflen(td, io_u, is_random);
if (!io_u->buflen) {
dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u);
return 1;
diff --git a/options.c b/options.c
index 3da376e..1816d0b 100644
--- a/options.c
+++ b/options.c
@@ -1558,6 +1558,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
.group = FIO_OPT_G_INVALID,
},
{
+ .name = "bs_is_seq_rand",
+ .lname = "Block size division is seq/random (not read/write)",
+ .type = FIO_OPT_BOOL,
+ .off1 = td_var_offset(bs_is_seq_rand),
+ .help = "Consider any blocksize setting to be sequential,ramdom",
+ .def = "0",
+ .parent = "blocksize",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_INVALID,
+ },
+ {
.name = "randrepeat",
.lname = "Random repeatable",
.type = FIO_OPT_BOOL,
diff --git a/profile.h b/profile.h
index 3c8d61f..de35e9b 100644
--- a/profile.h
+++ b/profile.h
@@ -10,8 +10,8 @@ struct prof_io_ops {
int (*td_init)(struct thread_data *);
void (*td_exit)(struct thread_data *);
- int (*fill_io_u_off)(struct thread_data *, struct io_u *);
- int (*fill_io_u_size)(struct thread_data *, struct io_u *);
+ int (*fill_io_u_off)(struct thread_data *, struct io_u *, unsigned int *);
+ int (*fill_io_u_size)(struct thread_data *, struct io_u *, unsigned int);
struct fio_file *(*get_next_file)(struct thread_data *);
int (*io_u_lat)(struct thread_data *, uint64_t);
diff --git a/thread_options.h b/thread_options.h
index 32677e2..eaafaee 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -105,6 +105,7 @@ struct thread_options {
unsigned int softrandommap;
unsigned int bs_unaligned;
unsigned int fsync_on_close;
+ unsigned int bs_is_seq_rand;
unsigned int random_distribution;
@@ -317,6 +318,7 @@ struct thread_options_pack {
uint32_t softrandommap;
uint32_t bs_unaligned;
uint32_t fsync_on_close;
+ uint32_t bs_is_seq_rand;
uint32_t random_distribution;
fio_fp64_t zipf_theta;
--
Jens Axboe
next prev parent reply other threads:[~2013-07-25 18:42 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CE142CC7.127F5%Antonio.Jose.Rodrigues.Neto@netapp.com>
2013-07-23 16:52 ` Helping to model this workload Neto, Antonio Jose Rodrigues
2013-07-25 16:45 ` Jens Axboe
2013-07-25 16:52 ` Neto, Antonio Jose Rodrigues
2013-07-25 18:27 ` Jens Axboe
2013-07-25 18:31 ` Neto, Antonio Jose Rodrigues
2013-07-25 18:42 ` Jens Axboe [this message]
2013-07-25 18:59 ` Neto, Antonio Jose Rodrigues
2013-07-25 19:02 ` Jens Axboe
2013-07-25 19:02 ` Neto, Antonio Jose Rodrigues
2013-07-25 19:03 ` Jens Axboe
2013-07-25 19:07 ` Neto, Antonio Jose Rodrigues
2013-07-25 19:11 ` Jens Axboe
2013-07-25 19:50 ` Neto, Antonio Jose Rodrigues
2013-07-26 14:22 ` Neto, Antonio Jose Rodrigues
2013-07-26 14:24 ` Jens Axboe
2013-07-26 14:28 ` Neto, Antonio Jose Rodrigues
2013-07-26 14:34 ` Jens Axboe
2013-07-26 14:35 ` Neto, Antonio Jose Rodrigues
2013-07-26 14:39 ` Neto, Antonio Jose Rodrigues
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130725184244.GI29296@kernel.dk \
--to=axboe@kernel.dk \
--cc=Antonio.Jose.Rodrigues.Neto@netapp.com \
--cc=fio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.