Recent changes

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

 



The following changes since commit 6f260b317f4cec3027f79b8b329dd3f98c3906ac:

  Correct basename usage for verify dump (2011-01-13 18:57:54 +0100)

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

Bruce Cran (1):
      Print error if max number of jobs is exceeded

Jens Axboe (9):
      We need libgen.h for basename()
      Change disk util / eta method from signal to thread
      Make sure that pattern verifies also dump contents
      Fix race in exit of eta/util thread
      Comment out ->buf_filled_len in pattern fill
      Eta/disk thread uses more than the minimum stack
      Cleanup some verify bits
      Fio 1.50-rc3
      Streamline pattern/meta verifies instead of special casing them

 fio.c     |   64 ++++++++++++-------------
 init.c    |    7 ++-
 options.c |    5 ++
 verify.c  |  157 +++++++++++++++++++++++++++++++++++--------------------------
 verify.h  |    1 +
 5 files changed, 132 insertions(+), 102 deletions(-)

---

Diff of recent changes:

diff --git a/fio.c b/fio.c
index e475a36..067aa24 100644
--- a/fio.c
+++ b/fio.c
@@ -64,8 +64,8 @@ static struct fio_mutex *startup_mutex;
 static struct fio_mutex *writeout_mutex;
 static volatile int fio_abort;
 static int exit_value;
-static timer_t ival_timer;
 static pthread_t gtod_thread;
+static pthread_t disk_util_thread;
 static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 
@@ -113,26 +113,6 @@ static void terminate_threads(int group_id)
 	}
 }
 
-static void status_timer_arm(void)
-{
-	struct itimerspec value;
-
-	value.it_value.tv_sec = 0;
-	value.it_value.tv_nsec = DISK_UTIL_MSEC * 1000000;
-	value.it_interval.tv_sec = 0;
-	value.it_interval.tv_nsec = DISK_UTIL_MSEC * 1000000;
-
-	timer_settime(ival_timer, 0, &value, NULL);
-}
-
-static void ival_fn(union sigval sig)
-{
-	if (threads) {
-		update_io_ticks();
-		print_thread_status();
-	}
-}
-
 /*
  * Happens on thread runs with ctrl-c, ignore our own SIGQUIT
  */
@@ -149,22 +129,41 @@ static void sig_int(int sig)
 	}
 }
 
-static void posix_timer_teardown(void)
+static void *disk_thread_main(void *data)
 {
-	timer_delete(ival_timer);
+	fio_mutex_up(startup_mutex);
+
+	while (threads) {
+		usleep(DISK_UTIL_MSEC * 1000);
+		if (!threads)
+			break;
+		update_io_ticks();
+		print_thread_status();
+	}
+
+	return NULL;
 }
 
-static void posix_timer_setup(void)
+static int create_disk_util_thread(void)
 {
-	struct sigevent evt;
+	int ret;
 
-	memset(&evt, 0, sizeof(evt));
-	evt.sigev_notify = SIGEV_THREAD;
-	evt.sigev_notify_function = ival_fn;
+	ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL);
+	if (ret) {
+		log_err("Can't create disk util thread: %s\n", strerror(ret));
+		return 1;
+	}
 
-	if (timer_create(FIO_TIMER_CLOCK, &evt, &ival_timer) < 0)
-		perror("timer_create");
+	ret = pthread_detach(disk_util_thread);
+	if (ret) {
+		log_err("Can't detatch disk util thread: %s\n", strerror(ret));
+		return 1;
+	}
 
+	dprint(FD_MUTEX, "wait on startup_mutex\n");
+	fio_mutex_down(startup_mutex);
+	dprint(FD_MUTEX, "done waiting on startup_mutex\n");
+	return 0;
 }
 
 static void set_sig_handlers(void)
@@ -1716,9 +1715,7 @@ int main(int argc, char *argv[])
 		return 1;
 
 	set_genesis_time();
-
-	posix_timer_setup();
-	status_timer_arm();
+	create_disk_util_thread();
 
 	cgroup_list = smalloc(sizeof(*cgroup_list));
 	INIT_FLIST_HEAD(cgroup_list);
@@ -1738,7 +1735,6 @@ int main(int argc, char *argv[])
 	sfree(cgroup_list);
 	sfree(cgroup_mnt);
 
-	posix_timer_teardown();
 	fio_mutex_remove(startup_mutex);
 	fio_mutex_remove(writeout_mutex);
 	return exit_value;
diff --git a/init.c b/init.c
index f3085bc..682135b 100644
--- a/init.c
+++ b/init.c
@@ -22,7 +22,7 @@
 
 #include "lib/getopt.h"
 
-static char fio_version_string[] = "fio 1.50-rc2";
+static char fio_version_string[] = "fio 1.50-rc3";
 
 #define FIO_RANDSEED		(0xb1899bedUL)
 
@@ -158,8 +158,11 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent)
 
 	if (global)
 		return &def_thread;
-	if (thread_number >= max_jobs)
+	if (thread_number >= max_jobs) {
+		log_err("error: maximum number of jobs (%d) reached.\n",
+				max_jobs);
 		return NULL;
+	}
 
 	td = &threads[thread_number++];
 	*td = *parent;
diff --git a/options.c b/options.c
index 37e68d2..163e508 100644
--- a/options.c
+++ b/options.c
@@ -675,6 +675,11 @@ static int str_verify_pattern_cb(void *data, const char *input)
 		}
 	}
 	td->o.verify_pattern_bytes = i;
+	/*
+	 * VERIFY_META could already be set
+	 */
+	if (td->o.verify == VERIFY_NONE)
+		td->o.verify = VERIFY_PATTERN;
 	return 0;
 }
 
diff --git a/verify.c b/verify.c
index 14d3213..3eac9ca 100644
--- a/verify.c
+++ b/verify.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <assert.h>
 #include <pthread.h>
+#include <libgen.h>
 
 #include "fio.h"
 #include "verify.h"
@@ -38,23 +39,38 @@ void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u
 			io_u->rand_seed = fill_random_buf(p, len);
 		break;
 	case 1:
+		/*
+		 * See below write barrier comment
+		 */
+#if 0
+		read_barrier();
 		if (io_u->buf_filled_len >= len) {
 			dprint(FD_VERIFY, "using already filled verify pattern b=0 len=%u\n", len);
 			return;
 		}
+#endif
 		dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
 		memset(p, td->o.verify_pattern[0], len);
+		/*
+		 * We need to ensure that the pattern stores are seen before
+		 * the fill length store, or we could observe headers that
+		 * aren't valid to the extent notified by the fill length
+		 */
+		write_barrier();
 		io_u->buf_filled_len = len;
 		break;
 	default: {
 		unsigned int i = 0, size = 0;
 		unsigned char *b = p;
 
+#if 0
+		read_barrier();
 		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;
 		}
+#endif
 		dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
 					td->o.verify_pattern_bytes, len);
 
@@ -65,12 +81,24 @@ void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u
 			memcpy(b+i, td->o.verify_pattern, size);
 			i += size;
 		}
+		write_barrier();
 		io_u->buf_filled_len = len;
 		break;
 		}
 	}
 }
 
+static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
+{
+	unsigned int hdr_inc;
+
+	hdr_inc = io_u->buflen;
+	if (td->o.verify_interval)
+		hdr_inc = td->o.verify_interval;
+
+	return hdr_inc;
+}
+
 static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
 				 unsigned long seed, int use_seed)
 {
@@ -80,10 +108,7 @@ static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
 
 	fill_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
 
-	hdr_inc = io_u->buflen;
-	if (td->o.verify_interval)
-		hdr_inc = td->o.verify_interval;
-
+	hdr_inc = get_hdr_inc(td, io_u);
 	header_num = 0;
 	for (; p < io_u->buf + io_u->buflen; p += hdr_inc) {
 		hdr = p;
@@ -154,6 +179,9 @@ static inline unsigned int __hdr_size(int verify_type)
 	case VERIFY_SHA1:
 		len = sizeof(struct vhdr_sha1);
 		break;
+	case VERIFY_PATTERN:
+		len = 0;
+		break;
 	default:
 		log_err("fio: unknown verify header!\n");
 		assert(0);
@@ -256,6 +284,7 @@ static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc)
 	dummy = *io_u;
 	dummy.buf = buf;
 	dummy.rand_seed = hdr->rand_seed;
+	dummy.buf_filled_len = 0;
 
 	fill_pattern_headers(td, &dummy, hdr->rand_seed, 1);
 
@@ -291,20 +320,67 @@ static inline void *io_u_verify_off(struct verify_header *hdr, struct vcont *vc)
 	return vc->io_u->buf + vc->hdr_num * hdr->len + hdr_size(hdr);
 }
 
-static int verify_io_u_meta(struct verify_header *hdr, struct thread_data *td,
-			    struct vcont *vc)
+static unsigned int hweight8(unsigned int w)
 {
+	unsigned int res = w - ((w >> 1) & 0x55);
+
+	res = (res & 0x33) + ((res >> 2) & 0x33);
+	return (res + (res >> 4)) & 0x0F;
+}
+
+static int verify_io_u_pattern(struct verify_header *hdr, struct vcont *vc)
+{
+	struct thread_data *td = vc->td;
+	struct io_u *io_u = vc->io_u;
+	char *buf, *pattern;
+	unsigned int hdr_size = __hdr_size(td->o.verify);
+	unsigned int len, mod, i;
+
+	pattern = td->o.verify_pattern;
+	buf = (void *) hdr + hdr_size;
+	len = get_hdr_inc(td, io_u) - hdr_size;
+	mod = hdr_size % td->o.verify_pattern_bytes;
+
+	for (i = 0; i < len; i++) {
+		if (buf[i] != pattern[mod]) {
+			unsigned int bits;
+
+			bits = hweight8(buf[i] ^ pattern[mod]);
+			log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
+				buf[i], pattern[mod], bits);
+			log_err("fio: bad pattern block offset %u\n", i);
+			dump_verify_buffers(hdr, vc);
+			return EILSEQ;
+		}
+		mod++;
+		if (mod == td->o.verify_pattern_bytes)
+			mod = 0;
+	}
+
+	return 0;
+}
+
+static int verify_io_u_meta(struct verify_header *hdr, struct vcont *vc)
+{
+	struct thread_data *td = vc->td;
 	struct vhdr_meta *vh = hdr_priv(hdr);
 	struct io_u *io_u = vc->io_u;
+	int ret = EILSEQ;
 
 	dprint(FD_VERIFY, "meta verify io_u %p, len %u\n", io_u, hdr->len);
 
 	if (vh->offset == io_u->offset + vc->hdr_num * td->o.verify_interval)
+		ret = 0;
+
+	if (td->o.verify_pattern_bytes)
+		ret |= verify_io_u_pattern(hdr, vc);
+
+	if (!ret)
 		return 0;
 
 	vc->name = "meta";
 	log_verify_failure(hdr, vc);
-	return EILSEQ;
+	return ret;
 }
 
 static int verify_io_u_sha512(struct verify_header *hdr, struct vcont *vc)
@@ -515,37 +591,6 @@ static int verify_io_u_md5(struct verify_header *hdr, struct vcont *vc)
 	return EILSEQ;
 }
 
-static unsigned int hweight8(unsigned int w)
-{
-	unsigned int res = w - ((w >> 1) & 0x55);
-
-	res = (res & 0x33) + ((res >> 2) & 0x33);
-	return (res + (res >> 4)) & 0x0F;
-}
-
-int verify_io_u_pattern(char *pattern, unsigned long pattern_size,
-			char *buf, unsigned int len, unsigned int mod)
-{
-	unsigned int i;
-
-	for (i = 0; i < len; i++) {
-		if (buf[i] != pattern[mod]) {
-			unsigned int bits;
-
-			bits = hweight8(buf[i] ^ pattern[mod]);
-			log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
-				buf[i], pattern[mod], bits);
-			log_err("fio: bad pattern block offset %u\n", i);
-			return EILSEQ;
-		}
-		mod++;
-		if (mod == pattern_size)
-			mod = 0;
-	}
-
-	return 0;
-}
-
 /*
  * Push IO verification to a separate thread
  */
@@ -619,9 +664,7 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
 		goto done;
 	}
 
-	hdr_inc = io_u->buflen;
-	if (td->o.verify_interval)
-		hdr_inc = td->o.verify_interval;
+	hdr_inc = get_hdr_inc(td, io_u);
 
 	ret = 0;
 	for (p = io_u->buf; p < io_u->buf + io_u->buflen;
@@ -648,30 +691,6 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
 			return EILSEQ;
 		}
 
-		if (td->o.verify_pattern_bytes) {
-			dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n",
-								io_u, hdr->len);
-			ret = verify_io_u_pattern(td->o.verify_pattern,
-				  td->o.verify_pattern_bytes,
-				  p + hdr_size,
-				  hdr_inc - hdr_size,
-				  hdr_size % td->o.verify_pattern_bytes);
-
-			if (ret) {
-				log_err("pattern: verify failed at file %s offset %llu, length %u\n",
-					io_u->file->file_name,
-					io_u->offset + hdr_num * hdr->len,
-					hdr->len);
-			}
-
-			/*
-			 * Also verify the meta data, if applicable
-			 */
-			if (hdr->verify_type == VERIFY_META)
-				ret |= verify_io_u_meta(hdr, td, &vc);
-			continue;
-		}
-
 		switch (hdr->verify_type) {
 		case VERIFY_MD5:
 			ret = verify_io_u_md5(hdr, &vc);
@@ -699,11 +718,14 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
 			ret = verify_io_u_sha512(hdr, &vc);
 			break;
 		case VERIFY_META:
-			ret = verify_io_u_meta(hdr, td, &vc);
+			ret = verify_io_u_meta(hdr, &vc);
 			break;
 		case VERIFY_SHA1:
 			ret = verify_io_u_sha1(hdr, &vc);
 			break;
+		case VERIFY_PATTERN:
+			ret = verify_io_u_pattern(hdr, &vc);
+			break;
 		default:
 			log_err("Bad verify type %u\n", hdr->verify_type);
 			ret = EINVAL;
@@ -882,6 +904,9 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u,
 						io_u, hdr->len);
 		fill_sha1(hdr, data, data_len);
 		break;
+	case VERIFY_PATTERN:
+		/* nothing to do here */
+		break;
 	default:
 		log_err("fio: bad verify type: %d\n", td->o.verify);
 		assert(0);
diff --git a/verify.h b/verify.h
index d5a906e..49ce417 100644
--- a/verify.h
+++ b/verify.h
@@ -18,6 +18,7 @@ enum {
 	VERIFY_SHA512,			/* sha512 sum data blocks */
 	VERIFY_META,			/* block_num, timestamp etc. */
 	VERIFY_SHA1,			/* sha1 sum data blocks */
+	VERIFY_PATTERN,			/* verify specific patterns */
 	VERIFY_NULL,			/* pretend to verify */
 };
 
--
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