From d72be5454c8c5378f16804ff9b8d1afe8729a380 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 30 Nov 2012 19:37:46 +0100 Subject: [PATCH 1/1] Cache layout improvements Signed-off-by: Jens Axboe --- fio.h | 11 +++++++++++ init.c | 20 ++++++++++++++++++++ io_u.c | 42 +++++++++++++++++++++++++++--------------- ioengine.h | 12 +++++------- profile.c | 4 +++- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/fio.h b/fio.h index 0100e3d8..d7cb4ab8 100644 --- a/fio.h +++ b/fio.h @@ -309,11 +309,22 @@ struct thread_options { unsigned int sync_file_range; }; +enum { + TD_F_VER_BACKLOG = 1, + TD_F_TRIM_BACKLOG = 2, + TD_F_READ_IOLOG = 4, + TD_F_REFILL_BUFFERS = 8, + TD_F_SCRAMBLE_BUFFERS = 16, + TD_F_VER_NONE = 32, + TD_F_PROFILE_OPS = 64, +}; + /* * This describes a single thread/process executing a fio job. */ struct thread_data { struct thread_options o; + unsigned long flags; void *eo; char verror[FIO_VERROR_SIZE]; pthread_t thread; diff --git a/init.c b/init.c index 29a50f22..563dcb75 100644 --- a/init.c +++ b/init.c @@ -767,6 +767,24 @@ int ioengine_load(struct thread_data *td) return 0; } +static void init_flags(struct thread_data *td) +{ + struct thread_options *o = &td->o; + + if (o->verify_backlog) + td->flags |= TD_F_VER_BACKLOG; + if (o->trim_backlog) + td->flags |= TD_F_TRIM_BACKLOG; + if (o->read_iolog_file) + td->flags |= TD_F_READ_IOLOG; + if (o->refill_buffers) + td->flags |= TD_F_REFILL_BUFFERS; + if (o->scramble_buffers) + td->flags |= TD_F_SCRAMBLE_BUFFERS; + if (o->verify != VERIFY_NONE) + td->flags |= TD_F_VER_NONE; +} + /* * Adds a job to the list of things todo. Sanitizes the various options * to make sure we don't have conflicts, and initializes various @@ -787,6 +805,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num) if (td == &def_thread) return 0; + init_flags(td); + /* * if we are just dumping the output command line, don't add the job */ diff --git a/io_u.c b/io_u.c index 006f2c9e..91d1290f 100644 --- a/io_u.c +++ b/io_u.c @@ -290,10 +290,12 @@ 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) { - struct prof_io_ops *ops = &td->prof_io_ops; + 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); + if (ops->fill_io_u_off) + return ops->fill_io_u_off(td, io_u); + } return __get_next_offset(td, io_u); } @@ -368,10 +370,12 @@ 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) { - struct prof_io_ops *ops = &td->prof_io_ops; + 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); + if (ops->fill_io_u_size) + return ops->fill_io_u_size(td, io_u); + } return __get_next_buflen(td, io_u); } @@ -960,10 +964,12 @@ out: static struct fio_file *get_next_file(struct thread_data *td) { - struct prof_io_ops *ops = &td->prof_io_ops; + if (!(td->flags & TD_F_PROFILE_OPS)) { + struct prof_io_ops *ops = &td->prof_io_ops; - if (ops->get_next_file) - return ops->get_next_file(td); + if (ops->get_next_file) + return ops->get_next_file(td); + } return __get_next_file(td); } @@ -1040,7 +1046,10 @@ again: static int check_get_trim(struct thread_data *td, struct io_u *io_u) { - if (td->o.trim_backlog && td->trim_entries) { + if (!(td->flags & TD_F_TRIM_BACKLOG)) + return 0; + + if (td->trim_entries) { int get_trim = 0; if (td->trim_batch) { @@ -1063,7 +1072,10 @@ static int check_get_trim(struct thread_data *td, struct io_u *io_u) static int check_get_verify(struct thread_data *td, struct io_u *io_u) { - if (td->o.verify_backlog && td->io_hist_len) { + if (!(td->flags & TD_F_VER_BACKLOG)) + return 0; + + if (td->io_hist_len) { int get_verify = 0; if (td->verify_batch) @@ -1154,7 +1166,7 @@ struct io_u *get_io_u(struct thread_data *td) /* * If using an iolog, grab next piece if any available. */ - if (td->o.read_iolog_file) { + if (td->flags & TD_F_READ_IOLOG) { if (read_iolog_get(td, io_u)) goto err_put; } else if (set_io_u_file(td, io_u)) { @@ -1175,12 +1187,12 @@ struct io_u *get_io_u(struct thread_data *td) f->last_pos = io_u->offset + io_u->buflen; if (io_u->ddir == DDIR_WRITE) { - if (td->o.refill_buffers) { + if (td->flags & TD_F_REFILL_BUFFERS) { io_u_fill_buffer(td, io_u, io_u->xfer_buflen, io_u->xfer_buflen); - } else if (td->o.scramble_buffers) + } else if (td->flags & TD_F_SCRAMBLE_BUFFERS) do_scramble = 1; - if (td->o.verify != VERIFY_NONE) { + if (td->flags & TD_F_VER_NONE) { populate_verify_io_u(td, io_u); do_scramble = 0; } diff --git a/ioengine.h b/ioengine.h index 61cb396f..e27dab1c 100644 --- a/ioengine.h +++ b/ioengine.h @@ -45,12 +45,16 @@ struct io_u { struct timeval start_time; struct timeval issue_time; + struct fio_file *file; + unsigned int flags; + enum fio_ddir ddir; + /* * Allocated/set buffer and length */ - void *buf; unsigned long buflen; unsigned long long offset; + void *buf; /* * Initial seed for generating the buffer contents @@ -73,8 +77,6 @@ struct io_u { unsigned int resid; unsigned int error; - enum fio_ddir ddir; - /* * io engine private data */ @@ -84,10 +86,6 @@ struct io_u { void *engine_data; }; - unsigned int flags; - - struct fio_file *file; - struct flist_head list; /* diff --git a/profile.c b/profile.c index 855dde3e..506462eb 100644 --- a/profile.c +++ b/profile.c @@ -93,8 +93,10 @@ void profile_add_hooks(struct thread_data *td) if (!ops) return; - if (ops->io_ops) + if (ops->io_ops) { td->prof_io_ops = *ops->io_ops; + td->flags |= TD_F_PROFILE_OPS; + } } int profile_td_init(struct thread_data *td) -- 2.25.1