Recent changes (master)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 04778baf2def8c1c5a3d7d60233c56d140831711:

  Add option to manually seed the random generators (2014-01-10 20:57:01 -0700)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Jens Axboe (1):
      Add option for specifically setting buffer contents

 HOWTO            |    5 ++++
 backend.c        |    2 +-
 fio.1            |    6 ++++
 io_u.c           |    4 ++-
 options.c        |   70 ++++++++++++++++++++++++++++++++++++++++-------------
 thread_options.h |    4 +++
 verify.c         |   62 +++++++++++++++++++++++++++++------------------
 verify.h         |    3 +-
 8 files changed, 112 insertions(+), 44 deletions(-)

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index 2183be1..c3672d8 100644
--- a/HOWTO
+++ b/HOWTO
@@ -547,6 +547,11 @@ buffer_compress_chunk=int	See buffer_compress_percentage. This
 		alternate random and zeroed data throughout the IO
 		buffer.
 
+buffer_pattern=str	If set, fio will fill the io buffers with this pattern.
+		If not set, the contents of io buffers is defined by the other
+		options related to buffer contents. The setting can be any
+		pattern of bytes, and can be prefixed with 0x for hex values.
+
 nrfiles=int	Number of files to use for this job. Defaults to 1.
 
 openfiles=int	Number of files to keep open at the same time. Defaults to
diff --git a/backend.c b/backend.c
index 101024d..c9a20a3 100644
--- a/backend.c
+++ b/backend.c
@@ -989,7 +989,7 @@ static int init_io_u(struct thread_data *td)
 				 * Fill the buffer with the pattern if we are
 				 * going to be doing writes.
 				 */
-				fill_pattern(td, io_u->buf, max_bs, io_u, 0, 0);
+				fill_verify_pattern(td, io_u->buf, max_bs, io_u, 0, 0);
 			}
 		}
 
diff --git a/fio.1 b/fio.1
index 6c3dd21..82d05b7 100644
--- a/fio.1
+++ b/fio.1
@@ -426,6 +426,12 @@ provide \fBbuffer_compress_percentage\fR of blocksize random data, followed by
 the remaining zeroed. With this set to some chunk size smaller than the block
 size, fio can alternate random and zeroed data throughout the IO buffer.
 .TP
+.BI buffer_pattern \fR=\fPstr
+If set, fio will fill the io buffers with this pattern. If not set, the contents
+of io buffers is defined by the other options related to buffer contents. The
+setting can be any pattern of bytes, and can be prefixed with 0x for hex
+values.
+.TP
 .BI nrfiles \fR=\fPint
 Number of files to use for this job.  Default: 1.
 .TP
diff --git a/io_u.c b/io_u.c
index ea6c251..518d884 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1770,7 +1770,9 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
 void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
 		    unsigned int max_bs)
 {
-	if (!td->o.zero_buffers) {
+	if (td->o.buffer_pattern_bytes)
+		fill_buffer_pattern(td, buf, max_bs);
+	else if (!td->o.zero_buffers) {
 		unsigned int perc = td->o.compress_percentage;
 
 		if (perc) {
diff --git a/options.c b/options.c
index 16b6636..b1b6c8e 100644
--- a/options.c
+++ b/options.c
@@ -834,11 +834,12 @@ static int str_opendir_cb(void *data, const char fio_unused *str)
 	return add_dir_files(td, td->o.opendir);
 }
 
-static int str_verify_pattern_cb(void *data, const char *input)
+static int pattern_cb(char *pattern, unsigned int max_size,
+		      const char *input, unsigned int *pattern_bytes)
 {
-	struct thread_data *td = data;
 	long off;
-	int i = 0, j = 0, len, k, base = 10, pattern_length;
+	int i = 0, j = 0, len, k, base = 10;
+	uint32_t pattern_length;
 	char *loc1, *loc2;
 
 	loc1 = strstr(input, "0x");
@@ -848,7 +849,7 @@ static int str_verify_pattern_cb(void *data, const char *input)
 	off = strtol(input, NULL, base);
 	if (off != LONG_MAX || errno != ERANGE) {
 		while (off) {
-			td->o.verify_pattern[i] = off & 0xff;
+			pattern[i] = off & 0xff;
 			off >>= 8;
 			i++;
 		}
@@ -862,13 +863,13 @@ static int str_verify_pattern_cb(void *data, const char *input)
 				j = loc2 - input + 2;
 		} else
 			return 1;
-		if (len - j < MAX_PATTERN_SIZE * 2) {
+		if (len - j < max_size * 2) {
 			while (k >= j) {
 				off = converthexchartoint(input[k--]);
 				if (k >= j)
 					off += (converthexchartoint(input[k--])
 						* 16);
-				td->o.verify_pattern[i++] = (char) off;
+				pattern[i++] = (char) off;
 			}
 		}
 	}
@@ -878,19 +879,19 @@ static int str_verify_pattern_cb(void *data, const char *input)
 	 * the number of memcpy's we have to do when verifying the IO.
 	 */
 	pattern_length = i;
-	while (i > 1 && i * 2 <= MAX_PATTERN_SIZE) {
-		memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], i);
+	while (i > 1 && i * 2 <= max_size) {
+		memcpy(&pattern[i], &pattern[0], i);
 		i *= 2;
 	}
 
 	/*
 	 * Fill remainder, if the pattern multiple ends up not being
-	 * MAX_PATTERN_SIZE.
+	 * max_size.
 	 */
-	while (i > 1 && i < MAX_PATTERN_SIZE) {
-		unsigned int b = min(pattern_length, MAX_PATTERN_SIZE - i);
+	while (i > 1 && i < max_size) {
+		unsigned int b = min(pattern_length, max_size - i);
 
-		memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], b);
+		memcpy(&pattern[i], &pattern[0], b);
 		i += b;
 	}
 
@@ -899,19 +900,45 @@ static int str_verify_pattern_cb(void *data, const char *input)
 		 * The code in verify_io_u_pattern assumes a single byte pattern
 		 * fills the whole verify pattern buffer.
 		 */
-		memset(td->o.verify_pattern, td->o.verify_pattern[0],
-		       MAX_PATTERN_SIZE);
+		memset(pattern, pattern[0], max_size);
+	}
+
+	*pattern_bytes = i;
+	return 0;
+}
+
+static int str_buffer_pattern_cb(void *data, const char *input)
+{
+	struct thread_data *td = data;
+	int ret;
+
+	ret = pattern_cb(td->o.buffer_pattern, MAX_PATTERN_SIZE, input,
+				&td->o.buffer_pattern_bytes);
+
+	if (!ret) {
+		td->o.refill_buffers = 0;
+		td->o.scramble_buffers = 0;
+		td->o.zero_buffers = 0;
 	}
 
-	td->o.verify_pattern_bytes = i;
+	return ret;
+}
+
+static int str_verify_pattern_cb(void *data, const char *input)
+{
+	struct thread_data *td = data;
+	int ret;
+
+	ret = pattern_cb(td->o.verify_pattern, MAX_PATTERN_SIZE, input,
+				&td->o.verify_pattern_bytes);
 
 	/*
 	 * VERIFY_META could already be set
 	 */
-	if (td->o.verify == VERIFY_NONE)
+	if (!ret && td->o.verify == VERIFY_NONE)
 		td->o.verify = VERIFY_PATTERN;
 
-	return 0;
+	return ret;
 }
 
 static int str_gtod_reduce_cb(void *data, int *il)
@@ -2947,6 +2974,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 		.group	= FIO_OPT_G_IO_BUF,
 	},
 	{
+		.name	= "buffer_pattern",
+		.lname	= "Buffer pattern",
+		.type	= FIO_OPT_STR,
+		.cb	= str_buffer_pattern_cb,
+		.help	= "Fill pattern for IO buffers",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_IO_BUF,
+	},
+	{
 		.name	= "buffer_compress_percentage",
 		.lname	= "Buffer compression percentage",
 		.type	= FIO_OPT_INT,
diff --git a/thread_options.h b/thread_options.h
index e2c6e88..f40a992 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -170,6 +170,8 @@ struct thread_options {
 	unsigned int zero_buffers;
 	unsigned int refill_buffers;
 	unsigned int scramble_buffers;
+	char buffer_pattern[MAX_PATTERN_SIZE];
+	unsigned int buffer_pattern_bytes;
 	unsigned int compress_percentage;
 	unsigned int compress_chunk;
 	unsigned int time_based;
@@ -381,6 +383,8 @@ struct thread_options_pack {
 	uint32_t zero_buffers;
 	uint32_t refill_buffers;
 	uint32_t scramble_buffers;
+	uint8_t buffer_pattern[MAX_PATTERN_SIZE];
+	uint32_t buffer_pattern_bytes;
 	unsigned int compress_percentage;
 	unsigned int compress_chunk;
 	uint32_t time_based;
diff --git a/verify.c b/verify.c
index 0d38c0e..721aeb4 100644
--- a/verify.c
+++ b/verify.c
@@ -28,51 +28,65 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u,
 			 struct verify_header *hdr, unsigned int header_num,
 			 unsigned int header_len);
 
-void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed)
+static void fill_pattern(struct thread_data *td, void *p, unsigned int len,
+			 char *pattern, unsigned int pattern_bytes)
 {
-	switch (td->o.verify_pattern_bytes) {
+	switch (pattern_bytes) {
 	case 0:
-		dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
-		if (use_seed)
-			__fill_random_buf(p, len, seed);
-		else
-			io_u->rand_seed = fill_random_buf(&td->buf_state, p, len);
+		assert(0);
 		break;
 	case 1:
-		if (io_u->buf_filled_len >= len) {
-			dprint(FD_VERIFY, "using already filled verify pattern b=0 len=%u\n", len);
-			return;
-		}
 		dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
-		memset(p, td->o.verify_pattern[0], len);
-		io_u->buf_filled_len = len;
+		memset(p, pattern[0], len);
 		break;
 	default: {
 		unsigned int i = 0, size = 0;
 		unsigned char *b = p;
 
-		if (io_u->buf_filled_len >= len) {
-			dprint(FD_VERIFY, "using already filled verify pattern b=%d len=%u\n",
-					td->o.verify_pattern_bytes, len);
-			return;
-		}
-
 		dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
-					td->o.verify_pattern_bytes, len);
+					pattern_bytes, len);
 
 		while (i < len) {
-			size = td->o.verify_pattern_bytes;
+			size = pattern_bytes;
 			if (size > (len - i))
 				size = len - i;
-			memcpy(b+i, td->o.verify_pattern, size);
+			memcpy(b+i, pattern, size);
 			i += size;
 		}
-		io_u->buf_filled_len = len;
 		break;
 		}
 	}
 }
 
+void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len)
+{
+	fill_pattern(td, p, len, td->o.buffer_pattern, td->o.buffer_pattern_bytes);
+}
+
+void fill_verify_pattern(struct thread_data *td, void *p, unsigned int len,
+			 struct io_u *io_u, unsigned long seed, int use_seed)
+{
+	if (!td->o.verify_pattern_bytes) {
+		dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
+
+		if (use_seed)
+			__fill_random_buf(p, len, seed);
+		else
+			io_u->rand_seed = fill_random_buf(&td->buf_state, p, len);
+		return;
+	}
+	
+	if (io_u->buf_filled_len >= len) {
+		dprint(FD_VERIFY, "using already filled verify pattern b=%d len=%u\n",
+			td->o.verify_pattern_bytes, len);
+		return;
+	}
+
+	fill_pattern(td, p, len, td->o.verify_pattern, td->o.verify_pattern_bytes);
+
+	io_u->buf_filled_len = len;
+}
+
 static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
 {
 	unsigned int hdr_inc;
@@ -91,7 +105,7 @@ static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
 	struct verify_header *hdr;
 	void *p = io_u->buf;
 
-	fill_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
+	fill_verify_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
 
 	hdr_inc = get_hdr_inc(td, io_u);
 	header_num = 0;
diff --git a/verify.h b/verify.h
index 6a81e9b..05d7b81 100644
--- a/verify.h
+++ b/verify.h
@@ -74,7 +74,8 @@ extern void populate_verify_io_u(struct thread_data *, struct io_u *);
 extern int __must_check get_next_verify(struct thread_data *td, struct io_u *);
 extern int __must_check verify_io_u(struct thread_data *, struct io_u *);
 extern int verify_io_u_async(struct thread_data *, struct io_u *);
-extern void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed);
+extern void fill_verify_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed);
+extern void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len);
 extern void fio_verify_init(struct thread_data *td);
 
 /*
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux