Cache layout improvements

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/fio.h b/fio.h
index 0100e3d..d7cb4ab 100644
--- a/fio.h
+++ b/fio.h
@@ -309,11 +309,22 @@
 	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 29a50f2..563dcb7 100644
--- a/init.c
+++ b/init.c
@@ -767,6 +767,24 @@
 	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 @@
 	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 006f2c9..91d1290 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)
 {
-	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)
 {
-	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 @@
 
 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 @@
 
 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_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 @@
 	/*
 	 * 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 @@
 		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 61cb396..e27dab1 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -45,12 +45,16 @@
 	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 @@
 	unsigned int resid;
 	unsigned int error;
 
-	enum fio_ddir ddir;
-
 	/*
 	 * io engine private data
 	 */
@@ -84,10 +86,6 @@
 		void *engine_data;
 	};
 
-	unsigned int flags;
-
-	struct fio_file *file;
-
 	struct flist_head list;
 
 	/*
diff --git a/profile.c b/profile.c
index 855dde3..506462e 100644
--- a/profile.c
+++ b/profile.c
@@ -93,8 +93,10 @@
 	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)