Recent changes (gfio)

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

 



The following changes since commit 2a988d8bcb447eb098fc382835cc507587c6ba66:

  Merge branch 'master' into gfio (2012-12-11 08:11:11 +0100)

are available in the git repository at:

  git://git.kernel.dk/fio.git gfio

Jens Axboe (5):
      file hash: don't close file fd on lookup/add race
      file: unify ->file_data and ->file_pos
      binject: fixup ->file_data breakage
      clock: ensure that we re-init if the clocksource changes from the default
      Merge branch 'master' into gfio

 engines/binject.c   |   16 ++++++++--------
 engines/e4defrag.c  |    3 ---
 engines/falloc.c    |    3 ---
 engines/fusion-aw.c |    1 -
 engines/sync.c      |    9 +++++++--
 file.h              |    5 ++---
 filesetup.c         |   44 ++++++++++++++++++++++++++++++++++++++++++--
 gettime.c           |    5 +++++
 gettime.h           |    1 +
 options.c           |    1 +
 10 files changed, 66 insertions(+), 22 deletions(-)

---

Diff of recent changes:

diff --git a/engines/binject.c b/engines/binject.c
index 47d40fe..f78d855 100644
--- a/engines/binject.c
+++ b/engines/binject.c
@@ -69,7 +69,7 @@ static unsigned int binject_read_commands(struct thread_data *td, void *p,
 one_more:
 	events = 0;
 	for_each_file(td, f, i) {
-		bf = f->file_data;
+		bf = (void *) f->engine_data;
 		ret = read(bf->fd, p, left * sizeof(struct b_user_cmd));
 		if (ret < 0) {
 			if (errno == EAGAIN)
@@ -104,7 +104,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
 	 * Fill in the file descriptors
 	 */
 	for_each_file(td, f, i) {
-		bf = f->file_data;
+		bf = (void *) f->engine_data;
 
 		/*
 		 * don't block for min events == 0
@@ -153,7 +153,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
 
 	if (!min) {
 		for_each_file(td, f, i) {
-			bf = f->file_data;
+			bf = (void *) f->engine_data;
 			fcntl(bf->fd, F_SETFL, bd->fd_flags[i]);
 		}
 	}
@@ -167,7 +167,7 @@ static int fio_binject_getevents(struct thread_data *td, unsigned int min,
 static int fio_binject_doio(struct thread_data *td, struct io_u *io_u)
 {
 	struct b_user_cmd *buc = &io_u->buc;
-	struct binject_file *bf = io_u->file->file_data;
+	struct binject_file *bf = (void *) io_u->file->engine_data;
 	int ret;
 
 	ret = write(bf->fd, buc, sizeof(*buc));
@@ -181,7 +181,7 @@ static int fio_binject_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct binject_data *bd = td->io_ops->data;
 	struct b_user_cmd *buc = &io_u->buc;
-	struct binject_file *bf = io_u->file->file_data;
+	struct binject_file *bf = (void *) io_u->file->engine_data;
 
 	if (io_u->xfer_buflen & (bf->bs - 1)) {
 		log_err("read/write not sector aligned\n");
@@ -323,12 +323,12 @@ err_unmap:
 
 static int fio_binject_close_file(struct thread_data *td, struct fio_file *f)
 {
-	struct binject_file *bf = f->file_data;
+	struct binject_file *bf = (void *) f->engine_data;
 
 	if (bf) {
 		binject_unmap_dev(td, bf);
 		free(bf);
-		f->file_data = NULL;
+		f->engine_data = 0;
 		return generic_close_file(td, f);
 	}
 
@@ -357,7 +357,7 @@ static int fio_binject_open_file(struct thread_data *td, struct fio_file *f)
 	bf = malloc(sizeof(*bf));
 	bf->bs = bs;
 	bf->minor = bf->fd = -1;
-	f->file_data = bf;
+	f->engine_data = (uint64_t) bf;
 
 	if (binject_map_dev(td, bf, f->fd)) {
 err_close:
diff --git a/engines/e4defrag.c b/engines/e4defrag.c
index e10cf36..6063e6c 100644
--- a/engines/e4defrag.c
+++ b/engines/e4defrag.c
@@ -161,9 +161,6 @@ static int fio_e4defrag_queue(struct thread_data *td, struct io_u *io_u)
 	ret = ioctl(f->fd, EXT4_IOC_MOVE_EXT, &me);
 	len = me.moved_len * ed->bsz;
 
-	if (io_u->file && len && ddir_rw(io_u->ddir))
-		io_u->file->file_pos = io_u->offset + len;
-
 	if (len > io_u->xfer_buflen)
 		len = io_u->xfer_buflen;
 
diff --git a/engines/falloc.c b/engines/falloc.c
index bc5ebd7..525a0aa 100644
--- a/engines/falloc.c
+++ b/engines/falloc.c
@@ -89,9 +89,6 @@ static int fio_fallocate_queue(struct thread_data *td, struct io_u *io_u)
 	if (ret)
 		io_u->error = errno;
 
-	if (io_u->file && ret == 0 && ddir_rw(io_u->ddir))
-		io_u->file->file_pos = io_u->offset + ret;
-
 	return FIO_Q_COMPLETED;
 }
 
diff --git a/engines/fusion-aw.c b/engines/fusion-aw.c
index 9aac43a..118c6dd 100644
--- a/engines/fusion-aw.c
+++ b/engines/fusion-aw.c
@@ -88,7 +88,6 @@ static int queue(struct thread_data *td, struct io_u *io_u)
 		goto out;
 	} else {
 		io_u->error = 0;
-		io_u->file->file_pos = io_u->offset + rc;
 		rc = FIO_Q_COMPLETED;
 	}
 
diff --git a/engines/sync.c b/engines/sync.c
index bd912e7..8779628 100644
--- a/engines/sync.c
+++ b/engines/sync.c
@@ -14,6 +14,11 @@
 
 #include "../fio.h"
 
+/*
+ * Sync engine uses engine_data to store last offset
+ */
+#define LAST_POS(f)	((f)->engine_data)
+
 struct syncio_data {
 	struct iovec *iovecs;
 	struct io_u **io_us;
@@ -33,7 +38,7 @@ static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
 	if (!ddir_rw(io_u->ddir))
 		return 0;
 
-	if (f->file_pos != -1ULL && f->file_pos == io_u->offset)
+	if (LAST_POS(f) != -1ULL && LAST_POS(f) == io_u->offset)
 		return 0;
 
 	if (lseek(f->fd, io_u->offset, SEEK_SET) == -1) {
@@ -47,7 +52,7 @@ static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
 static int fio_io_end(struct thread_data *td, struct io_u *io_u, int ret)
 {
 	if (io_u->file && ret >= 0 && ddir_rw(io_u->ddir))
-		io_u->file->file_pos = io_u->offset + ret;
+		LAST_POS(io_u->file) = io_u->offset + ret;
 
 	if (ret != (int) io_u->xfer_buflen) {
 		if (ret >= 0) {
diff --git a/file.h b/file.h
index 3024c54..e57bebc 100644
--- a/file.h
+++ b/file.h
@@ -63,8 +63,8 @@ struct fio_file {
 	struct flist_head hash_list;
 	enum fio_filetype filetype;
 
-	void *file_data;
 	int fd;
+	int shadow_fd;
 #ifdef WIN32
 	HANDLE hFile;
 	HANDLE ioCP;
@@ -97,7 +97,7 @@ struct fio_file {
 	/*
 	 * For use by the io engine
 	 */
-	unsigned long long file_pos;
+	uint64_t engine_data;
 
 	/*
 	 * if io is protected by a semaphore, this is set
@@ -180,7 +180,6 @@ static inline void fio_file_reset(struct fio_file *f)
 {
 	f->last_pos = f->file_offset;
 	f->last_start = -1ULL;
-	f->file_pos = -1ULL;
 	if (f->io_axmap)
 		axmap_reset(f->io_axmap);
 }
diff --git a/filesetup.c b/filesetup.c
index 3462a03..60894c4 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -434,6 +434,12 @@ int generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
 		ret = errno;
 
 	f->fd = -1;
+
+	if (f->shadow_fd != -1) {
+		close(f->shadow_fd);
+		f->shadow_fd = -1;
+	}
+
 	return ret;
 }
 
@@ -462,6 +468,24 @@ int file_lookup_open(struct fio_file *f, int flags)
 	return from_hash;
 }
 
+static int file_close_shadow_fds(struct thread_data *td)
+{
+	struct fio_file *f;
+	int num_closed = 0;
+	unsigned int i;
+
+	for_each_file(td, f, i) {
+		if (f->shadow_fd == -1)
+			continue;
+
+		close(f->shadow_fd);
+		f->shadow_fd = -1;
+		num_closed++;
+	}
+
+	return num_closed;
+}
+
 int generic_open_file(struct thread_data *td, struct fio_file *f)
 {
 	int is_std = 0;
@@ -536,6 +560,8 @@ open_again:
 			flags &= ~FIO_O_NOATIME;
 			goto open_again;
 		}
+		if (__e == EMFILE && file_close_shadow_fds(td))
+			goto open_again;
 
 		snprintf(buf, sizeof(buf) - 1, "open(%s)", f->file_name);
 
@@ -552,9 +578,22 @@ open_again:
 			int fio_unused ret;
 
 			/*
-			 * OK to ignore, we haven't done anything with it
+			 * Stash away descriptor for later close. This is to
+			 * work-around a "feature" on Linux, where a close of
+			 * an fd that has been opened for write will trigger
+			 * udev to call blkid to check partitions, fs id, etc.
+			 * That polutes the device cache, which can slow down
+			 * unbuffered accesses.
 			 */
-			ret = generic_close_file(td, f);
+			if (f->shadow_fd == -1)
+				f->shadow_fd = f->fd;
+			else {
+				/*
+			 	 * OK to ignore, we haven't done anything
+				 * with it
+				 */
+				ret = generic_close_file(td, f);
+			}
 			goto open_again;
 		}
 	}
@@ -1029,6 +1068,7 @@ int add_file(struct thread_data *td, const char *fname)
 	}
 
 	f->fd = -1;
+	f->shadow_fd = -1;
 	fio_file_reset(f);
 
 	if (td->files_size <= td->files_index) {
diff --git a/gettime.c b/gettime.c
index 1ba18e9..9f23e3f 100644
--- a/gettime.c
+++ b/gettime.c
@@ -22,6 +22,7 @@ static int last_tv_valid;
 
 enum fio_cs fio_clock_source = FIO_PREFERRED_CLOCK_SOURCE;
 int fio_clock_source_set = 0;
+enum fio_cs fio_clock_source_inited = CS_INVAL;
 
 #ifdef FIO_DEBUG_TIME
 
@@ -262,7 +263,11 @@ static void calibrate_cpu_clock(void)
 
 void fio_clock_init(void)
 {
+	if (fio_clock_source == fio_clock_source_inited)
+		return;
+
 	last_tv_valid = 0;
+	fio_clock_source_inited = fio_clock_source;
 	calibrate_cpu_clock();
 
 	/*
diff --git a/gettime.h b/gettime.h
index 309ef21..64651a1 100644
--- a/gettime.h
+++ b/gettime.h
@@ -8,6 +8,7 @@ enum fio_cs {
 	CS_GTOD		= 1,
 	CS_CGETTIME,
 	CS_CPUCLOCK,
+	CS_INVAL,
 };
 
 extern void fio_gettime(struct timeval *, void *);
diff --git a/options.c b/options.c
index 917dbf0..a7a133f 100644
--- a/options.c
+++ b/options.c
@@ -360,6 +360,7 @@ static int fio_clock_source_cb(void *data, const char *str)
 
 	fio_clock_source = td->o.clocksource;
 	fio_clock_source_set = 1;
+	fio_clock_init();
 	return 0;
 }
 
--
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