Recent changes

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

 



The following changes since commit c604fb8eea323d8dbf948f238f61f12dadf821af:

  Fio 1.41 (2010-06-18 14:49:46 +0200)

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

Jens Axboe (12):
      Fix a bug with multiple files in the same io_piece rbtree
      Fio 1.41.1
      Do diskutil check earlier
      Fix disk util for slaves
      Fio 1.41.2
      Add documentation for verify_backlog and verify_backlog_batch
      Cleanup up SIGILL for crc32c-intel
      Missing new line
      Auto-detect missing hw support for crc32c and fallback to software
      Documentation update
      Speedup verify random fills by 10-15x
      Fio 1.41.3

 HOWTO              |   20 +++++++++++++++++++-
 crc/crc32c-intel.c |   40 +++++++++++++++++++++++++++++++++++++++-
 crc/crc32c.h       |    5 +++++
 diskutil.c         |   16 +++++++++++++---
 fio.1              |   18 +++++++++++++++++-
 fio.c              |   16 ----------------
 init.c             |    2 +-
 io_u.c             |   20 ++++----------------
 lib/rand.c         |   17 +++++++++++++++++
 lib/rand.h         |    1 +
 log.c              |    6 +++++-
 options.c          |   18 ++++++++++++++++++
 verify.c           |   26 ++------------------------
 13 files changed, 141 insertions(+), 64 deletions(-)

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index 19304ae..3e1e62a 100644
--- a/HOWTO
+++ b/HOWTO
@@ -823,7 +823,9 @@ verify=str	If writing to a file, fio can verify the file contents
 				it in the header of each block.
 
 			crc32c-intel Use hardware assisted crc32c calcuation
-				provided on SSE4.2 enabled processors.
+				provided on SSE4.2 enabled processors. Falls
+				back to regular software crc32c, if not
+				supported by the system.
 
 			crc32	Use a crc32 sum of the data area and store
 				it in the header of each block.
@@ -899,6 +901,22 @@ verify_async=int	Fio will normally verify IO inline from the submitting
 verify_async_cpus=str	Tell fio to set the given CPU affinity on the
 		async IO verification threads. See cpus_allowed for the
 		format used.
+
+verify_backlog=int	Fio will normally verify the written contents of a
+		job that utilizes verify once that job has completed. In
+		other words, everything is written then everything is read
+		back and verified. You may want to verify continually
+		instead for a variety of reasons. Fio stores the meta data
+		associated with an IO block in memory, so for large
+		verify workloads, quite a bit of memory would be used up
+		holding this meta data. If this option is enabled, fio
+		will verify the previously written blocks before continuing
+		to write new ones.
+
+verify_backlog_batch=int	Control how many blocks fio will verify
+		if verify_backlog is set. If not set, will default to
+		the value of verify_backlog (meaning the entire queue
+		is read back and verified).
 		
 stonewall	Wait for preceeding jobs in the job file to exit, before
 		starting this one. Can be used to insert serialization
diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c
index cec5ad5..fc106fa 100644
--- a/crc/crc32c-intel.c
+++ b/crc/crc32c-intel.c
@@ -1,4 +1,10 @@
 #include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include "crc32c.h"
 
 /*
@@ -68,5 +74,37 @@ uint32_t crc32c_intel(unsigned char const *data, unsigned long length)
 	return crc;
 }
 
-#endif /* ARCH_HAVE_SSE */
+static void sig_ill(int sig)
+{
+}
+
+static void crc32c_test(void)
+{
+	unsigned char buf[4] = { 1, 2, 3, 4 };
+	struct sigaction act;
+
+	/*
+	 * Check if hw accelerated crc32c is available
+	 */
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = sig_ill;
+	act.sa_flags = SA_RESETHAND;
+	sigaction(SIGILL, &act, NULL);
+
+	(void) crc32c_intel(buf, sizeof(buf));
+}
+
+int crc32c_intel_works(void)
+{
+	if (!fork()) {
+		crc32c_test();
+		exit(0);
+	} else {
+		int status;
 
+		wait(&status);
+		return !WIFSIGNALED(status);
+	}
+}
+
+#endif /* ARCH_HAVE_SSE */
diff --git a/crc/crc32c.h b/crc/crc32c.h
index 0976261..50f3665 100644
--- a/crc/crc32c.h
+++ b/crc/crc32c.h
@@ -24,8 +24,13 @@ extern uint32_t crc32c(unsigned char const *, unsigned long);
 
 #ifdef ARCH_HAVE_SSE
 extern uint32_t crc32c_intel(unsigned char const *, unsigned long);
+extern int crc32c_intel_works(void);
 #else
 #define crc32c_intel crc32c
+static inline int crc32c_intel_works(void)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/diskutil.c b/diskutil.c
index e90096b..4f705c9 100644
--- a/diskutil.c
+++ b/diskutil.c
@@ -24,6 +24,14 @@ static void disk_util_free(struct disk_util *du)
 	if (du == last_du)
 		last_du = NULL;
 
+	while (!flist_empty(&du->slaves)) {
+		struct disk_util *slave;
+
+		slave = flist_entry(du->slaves.next, struct disk_util, slavelist);
+		flist_del(&slave->slavelist);
+		slave->users--;
+	}
+	
 	fio_mutex_remove(du->lock);
 	sfree(du->name);
 	sfree(du);
@@ -67,10 +75,10 @@ static void update_io_tick_disk(struct disk_util *du)
 	struct disk_util_stat __dus, *dus, *ldus;
 	struct timeval t;
 
-	if (get_io_ticks(du, &__dus))
-		return;
 	if (!du->users)
 		return;
+	if (get_io_ticks(du, &__dus))
+		return;
 
 	dus = &du->dus;
 	ldus = &du->last_dus;
@@ -236,8 +244,10 @@ static void find_add_disk_slaves(struct thread_data *td, char *path,
 
 		/* Should probably use an assert here. slavedu should
 		 * always be present at this point. */
-		if (slavedu)
+		if (slavedu) {
+			slavedu->users++;
 			flist_add_tail(&slavedu->slavelist, &masterdu->slaves);
+		}
 	}
 
 	closedir(dirhandle);
diff --git a/fio.1 b/fio.1
index ac729df..e737906 100644
--- a/fio.1
+++ b/fio.1
@@ -602,7 +602,9 @@ values are:
 .RS
 .TP
 .B md5 crc16 crc32 crc32c crc32c-intel crc64 crc7 sha256 sha512 sha1
-Store appropriate checksum in the header of each block.
+Store appropriate checksum in the header of each block. crc32c-intel is
+hardware accelerated SSE4.2 driven, falls back to regular crc32c if
+not supported by the system.
 .TP
 .B meta
 Write extra information about each I/O (timestamp, block number, etc.). The
@@ -653,6 +655,20 @@ allows them to have IO in flight while verifies are running.
 Tell fio to set the given CPU affinity on the async IO verification threads.
 See \fBcpus_allowed\fP for the format used.
 .TP
+.BI verify_backlog \fR=\fPint
+Fio will normally verify the written contents of a job that utilizes verify
+once that job has completed. In other words, everything is written then
+everything is read back and verified. You may want to verify continually
+instead for a variety of reasons. Fio stores the meta data associated with an
+IO block in memory, so for large verify workloads, quite a bit of memory would
+be used up holding this meta data. If this option is enabled, fio will verify
+the previously written blocks before continuing to write new ones.
+.TP
+.BI verify_backlog_batch \fR=\fPint
+Control how many blocks fio will verify if verify_backlog is set. If not set,
+will default to the value of \fBverify_backlog\fR (meaning the entire queue is
+read back and verified).
+.TP
 .B stonewall
 Wait for preceeding jobs in the job file to exit before starting this one.
 \fBstonewall\fR implies \fBnew_group\fR.
diff --git a/fio.c b/fio.c
index ae62d23..b2a08bf 100644
--- a/fio.c
+++ b/fio.c
@@ -142,17 +142,6 @@ static void sig_int(int sig)
 	}
 }
 
-static void sig_ill(int fio_unused sig)
-{
-	if (!threads)
-		return;
-
-	log_err("fio: illegal instruction. your cpu does not support "
-		"the sse4.2 instruction for crc32c\n");
-	terminate_threads(TERMINATE_ALL);
-	exit(4);
-}
-
 static void set_sig_handlers(void)
 {
 	struct sigaction act;
@@ -168,11 +157,6 @@ static void set_sig_handlers(void)
 	sigaction(SIGINT, &act, NULL);
 
 	memset(&act, 0, sizeof(act));
-	act.sa_handler = sig_ill;
-	act.sa_flags = SA_RESTART;
-	sigaction(SIGILL, &act, NULL);
-
-	memset(&act, 0, sizeof(act));
 	act.sa_handler = sig_quit;
 	act.sa_flags = SA_RESTART;
 	sigaction(SIGQUIT, &act, NULL);
diff --git a/init.c b/init.c
index ae7a4d2..fad487d 100644
--- a/init.c
+++ b/init.c
@@ -21,7 +21,7 @@
 #include "verify.h"
 #include "profile.h"
 
-static char fio_version_string[] = "fio 1.41";
+static char fio_version_string[] = "fio 1.41.3";
 
 #define FIO_RANDSEED		(0xb1899bedUL)
 
diff --git a/io_u.c b/io_u.c
index f451d1a..69edd70 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1240,20 +1240,8 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
 void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
 		      unsigned int max_bs)
 {
-	long *ptr = io_u->buf;
-
-	if (!td->o.zero_buffers) {
-		unsigned long r = __rand(&__fio_rand_state);
-
-		if (sizeof(int) != sizeof(*ptr))
-			r *= (unsigned long) __rand(&__fio_rand_state);
-
-		while ((void *) ptr - io_u->buf < max_bs) {
-			*ptr = r;
-			ptr++;
-			r *= GOLDEN_RATIO_PRIME;
-			r >>= 3;
-		}
-	} else
-		memset(ptr, 0, max_bs);
+	if (!td->o.zero_buffers)
+		fill_random_buf(io_u->buf, max_bs);
+	else
+		memset(io_u->buf, 0, max_bs);
 }
diff --git a/lib/rand.c b/lib/rand.c
index cecc4c2..839a6a9 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -34,6 +34,7 @@
 */
 
 #include "rand.h"
+#include "../hash.h"
 
 struct frand_state __fio_rand_state;
 
@@ -57,3 +58,19 @@ void init_rand(struct frand_state *state)
 	__rand(state);
 	__rand(state);
 }
+
+void fill_random_buf(void *buf, unsigned int len)
+{
+	unsigned long r = __rand(&__fio_rand_state);
+	long *ptr = buf;
+
+	if (sizeof(int) != sizeof(*ptr))
+		r *= (unsigned long) __rand(&__fio_rand_state);
+
+	while ((void *) ptr - buf < len) {
+		*ptr = r;
+		ptr++;
+		r *= GOLDEN_RATIO_PRIME;
+		r >>= 3;
+	}
+}
diff --git a/lib/rand.h b/lib/rand.h
index 363e7b6..573116c 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -19,5 +19,6 @@ static inline unsigned int __rand(struct frand_state *state)
 }
 
 extern void init_rand(struct frand_state *);
+extern void fill_random_buf(void *buf, unsigned int len);
 
 #endif
diff --git a/log.c b/log.c
index 6a99c66..5fc8f64 100644
--- a/log.c
+++ b/log.c
@@ -219,7 +219,11 @@ restart:
 		parent = *p;
 
 		__ipo = rb_entry(parent, struct io_piece, rb_node);
-		if (ipo->offset < __ipo->offset)
+		if (ipo->file < __ipo->file)
+			p = &(*p)->rb_left;
+		else if (ipo->file > __ipo->file)
+			p = &(*p)->rb_right;
+		else if (ipo->offset < __ipo->offset)
 			p = &(*p)->rb_left;
 		else if (ipo->offset > __ipo->offset)
 			p = &(*p)->rb_right;
diff --git a/options.c b/options.c
index f470b45..fb18748 100644
--- a/options.c
+++ b/options.c
@@ -16,6 +16,8 @@
 #include "lib/fls.h"
 #include "options.h"
 
+#include "crc/crc32c.h"
+
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
  */
@@ -225,6 +227,21 @@ static int str_mem_cb(void *data, const char *mem)
 	return 0;
 }
 
+static int str_verify_cb(void *data, const char *mem)
+{
+	struct thread_data *td = data;
+
+	if (td->o.verify != VERIFY_CRC32C_INTEL)
+		return 0;
+
+	if (!crc32c_intel_works()) {
+		log_info("fio: System does not support hw accelerated crc32c. Falling back to sw crc32c.\n");
+		td->o.verify = VERIFY_CRC32C;
+	}
+
+	return 0;
+}
+
 static int fio_clock_source_cb(void *data, const char *str)
 {
 	struct thread_data *td = data;
@@ -1298,6 +1315,7 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.type	= FIO_OPT_STR,
 		.off1	= td_var_offset(verify),
 		.help	= "Verify data written",
+		.cb	= str_verify_cb,
 		.def	= "0",
 		.posval = {
 			  { .ival = "0",
diff --git a/verify.c b/verify.c
index 6b54b70..265bd55 100644
--- a/verify.c
+++ b/verify.c
@@ -10,6 +10,7 @@
 #include "fio.h"
 #include "verify.h"
 #include "smalloc.h"
+#include "lib/rand.h"
 
 #include "crc/md5.h"
 #include "crc/crc64.h"
@@ -21,35 +22,12 @@
 #include "crc/sha512.h"
 #include "crc/sha1.h"
 
-static void fill_random_bytes(struct thread_data *td, void *p, unsigned int len)
-{
-	unsigned int todo;
-	int r;
-
-	while (len) {
-		r = os_random_long(&td->verify_state);
-
-		/*
-		 * lrand48_r seems to be broken and only fill the bottom
-		 * 32-bits, even on 64-bit archs with 64-bit longs
-		 */
-		todo = sizeof(r);
-		if (todo > len)
-			todo = len;
-
-		memcpy(p, &r, todo);
-
-		len -= todo;
-		p += todo;
-	}
-}
-
 static void fill_pattern(struct thread_data *td, void *p, unsigned int len)
 {
 	switch (td->o.verify_pattern_bytes) {
 	case 0:
 		dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
-		fill_random_bytes(td, p, len);
+		fill_random_buf(p, len);
 		break;
 	case 1:
 		dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
--
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