Recent changes (master)

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

 



The following changes since commit 669e8bf8d509458aa6b3978b9e8a2e3d666e892d:

  server: make the setsockopt() error output a bit more informative (2015-07-29 09:00:03 -0600)

are available in the git repository at:

  git://git.kernel.dk/fio.git master

for you to fetch changes up to 92060d6c59f1848e86cd9ddd7550907c79bda3d5:

  arch-ppc.h: Add ilog2 implementation for ppc64 (2015-08-13 12:45:20 -0600)

----------------------------------------------------------------
Chandan Rajendra (1):
      arch-ppc.h: Add ilog2 implementation for ppc64

DaveGlen (2):
      Implement new Rate Control
      initialize rate_io_issue_bytes

Jens Axboe (1):
      Whitespace fixup

 arch/arch-ppc.h | 12 ++++++++---
 backend.c       | 26 ++++++++++++++++++++++
 fio.h           |  3 ++-
 init.c          |  3 ++-
 io_u.c          | 67 +++++++++++++++------------------------------------------
 ioengines.c     |  2 ++
 libfio.c        |  2 ++
 workqueue.c     |  1 +
 8 files changed, 61 insertions(+), 55 deletions(-)

---

Diff of recent changes:

diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h
index d4a080c..aed41f9 100644
--- a/arch/arch-ppc.h
+++ b/arch/arch-ppc.h
@@ -33,18 +33,24 @@
 
 #define write_barrier()	__asm__ __volatile__ ("sync" : : : "memory")
 
+#ifdef __powerpc64__
+#define PPC_CNTLZL "cntlzd"
+#else
+#define PPC_CNTLZL "cntlzw"
+#endif
+
 static inline int __ilog2(unsigned long bitmask)
 {
 	int lz;
 
-	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bitmask));
-	return 31 - lz;
+	asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (bitmask));
+	return BITS_PER_LONG - 1 - lz;
 }
 
 static inline int arch_ffz(unsigned long bitmask)
 {
 	if ((bitmask = ~bitmask) == 0)
-		return 32;
+		return BITS_PER_LONG;
 	return  __ilog2(bitmask & -bitmask);
 }
 
diff --git a/backend.c b/backend.c
index 3eafff6..9307667 100644
--- a/backend.c
+++ b/backend.c
@@ -763,6 +763,25 @@ static int io_complete_bytes_exceeded(struct thread_data *td)
 }
 
 /*
+ * used to calculate the next io time for rate control
+ *
+ */
+static long long usec_for_io(struct thread_data *td, enum fio_ddir ddir)
+{
+	uint64_t secs, remainder, bps, bytes;
+
+	assert(!(td->flags & TD_F_CHILD));
+	bytes = td->rate_io_issue_bytes[ddir];
+	bps = td->rate_bps[ddir];
+	if (bps) {
+		secs = bytes / bps;
+		remainder = bytes % bps;
+		return remainder * 1000000 / bps + secs * 1000000;
+	} else
+		return 0;
+}
+
+/*
  * Main IO worker function. It retrieves io_u's to process and queues
  * and reaps them, checking for rate and errors along the way.
  *
@@ -891,9 +910,16 @@ static uint64_t do_io(struct thread_data *td)
 			if (td->error)
 				break;
 			ret = workqueue_enqueue(&td->io_wq, io_u);
+
+			if (should_check_rate(td))
+				td->rate_next_io_time[ddir] = usec_for_io(td, ddir);
+
 		} else {
 			ret = td_io_queue(td, io_u);
 
+			if (should_check_rate(td))
+				td->rate_next_io_time[ddir] = usec_for_io(td, ddir);
+
 			if (io_queue_event(td, io_u, &ret, ddir, &bytes_issued, 0, &comp_time))
 				break;
 
diff --git a/fio.h b/fio.h
index 81d58e8..17bc02b 100644
--- a/fio.h
+++ b/fio.h
@@ -238,9 +238,10 @@ struct thread_data {
 	 * Rate state
 	 */
 	uint64_t rate_bps[DDIR_RWDIR_CNT];
-	long rate_pending_usleep[DDIR_RWDIR_CNT];
+	unsigned long rate_next_io_time[DDIR_RWDIR_CNT];
 	unsigned long rate_bytes[DDIR_RWDIR_CNT];
 	unsigned long rate_blocks[DDIR_RWDIR_CNT];
+	unsigned long rate_io_issue_bytes[DDIR_RWDIR_CNT];
 	struct timeval lastrate[DDIR_RWDIR_CNT];
 
 	/*
diff --git a/init.c b/init.c
index 5edd53e..8e1f295 100644
--- a/init.c
+++ b/init.c
@@ -465,7 +465,8 @@ static int __setup_rate(struct thread_data *td, enum fio_ddir ddir)
 		return -1;
 	}
 
-	td->rate_pending_usleep[ddir] = 0;
+	td->rate_next_io_time[ddir] = 0;
+	td->rate_io_issue_bytes[ddir] = 0;
 	return 0;
 }
 
diff --git a/io_u.c b/io_u.c
index d80ef98..9f10206 100644
--- a/io_u.c
+++ b/io_u.c
@@ -568,49 +568,47 @@ void io_u_quiesce(struct thread_data *td)
 static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
 {
 	enum fio_ddir odir = ddir ^ 1;
-	long usec;
+	long usec, now;
 
 	assert(ddir_rw(ddir));
+	now = utime_since_now(&td->start);
 
-	if (td->rate_pending_usleep[ddir] <= 0)
+	/*
+	 * if rate_next_io_time is in the past, need to catch up to rate
+	 */
+	if (td->rate_next_io_time[ddir] <= now)
 		return ddir;
 
 	/*
-	 * We have too much pending sleep in this direction. See if we
+	 * We are ahead of rate in this direction. See if we
 	 * should switch.
 	 */
 	if (td_rw(td) && td->o.rwmix[odir]) {
 		/*
-		 * Other direction does not have too much pending, switch
+		 * Other direction is behind rate, switch
 		 */
-		if (td->rate_pending_usleep[odir] < 100000)
+		if (td->rate_next_io_time[odir] <= now)
 			return odir;
 
 		/*
-		 * Both directions have pending sleep. Sleep the minimum time
-		 * and deduct from both.
+		 * Both directions are ahead of rate. sleep the min
+		 * switch if necissary
 		 */
-		if (td->rate_pending_usleep[ddir] <=
-			td->rate_pending_usleep[odir]) {
-			usec = td->rate_pending_usleep[ddir];
+		if (td->rate_next_io_time[ddir] <=
+			td->rate_next_io_time[odir]) {
+			usec = td->rate_next_io_time[ddir] - now;
 		} else {
-			usec = td->rate_pending_usleep[odir];
+			usec = td->rate_next_io_time[odir] - now;
 			ddir = odir;
 		}
 	} else
-		usec = td->rate_pending_usleep[ddir];
+		usec = td->rate_next_io_time[ddir] - now;
 
 	if (td->o.io_submit_mode == IO_MODE_INLINE)
 		io_u_quiesce(td);
 
 	usec = usec_sleep(td, usec);
 
-	td->rate_pending_usleep[ddir] -= usec;
-
-	odir = ddir ^ 1;
-	if (td_rw(td) && __should_check_rate(td, odir))
-		td->rate_pending_usleep[odir] -= usec;
-
 	return ddir;
 }
 
@@ -1656,18 +1654,6 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
 	}
 }
 
-static long long usec_for_io(struct thread_data *td, enum fio_ddir ddir)
-{
-	uint64_t secs, remainder, bps, bytes;
-
-	assert(!(td->flags & TD_F_CHILD));
-	bytes = td->this_io_bytes[ddir];
-	bps = td->rate_bps[ddir];
-	secs = bytes / bps;
-	remainder = bytes % bps;
-	return remainder * 1000000 / bps + secs * 1000000;
-}
-
 static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
 			 struct io_completion_data *icd)
 {
@@ -1709,7 +1695,6 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
 
 	if (!io_u->error && ddir_rw(ddir)) {
 		unsigned int bytes = io_u->buflen - io_u->resid;
-		const enum fio_ddir oddir = ddir ^ 1;
 		int ret;
 
 		td->io_blocks[ddir]++;
@@ -1738,27 +1723,9 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
 		}
 
 		if (ramp_time_over(td) && (td->runstate == TD_RUNNING ||
-					   td->runstate == TD_VERIFYING)) {
-			struct thread_data *__td = td;
-
+					   td->runstate == TD_VERIFYING))
 			account_io_completion(td, io_u, icd, ddir, bytes);
 
-			if (td->parent)
-				__td = td->parent;
-
-			if (__should_check_rate(__td, ddir)) {
-				__td->rate_pending_usleep[ddir] =
-					(usec_for_io(__td, ddir) -
-					 utime_since_now(&__td->start));
-			}
-			if (ddir != DDIR_TRIM &&
-			    __should_check_rate(__td, oddir)) {
-				__td->rate_pending_usleep[oddir] =
-					(usec_for_io(__td, oddir) -
-					 utime_since_now(&__td->start));
-			}
-		}
-
 		icd->bytes_done[ddir] += bytes;
 
 		if (io_u->end_io) {
diff --git a/ioengines.c b/ioengines.c
index 958731d..9c5ac60 100644
--- a/ioengines.c
+++ b/ioengines.c
@@ -299,6 +299,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
 	if (ddir_rw(ddir)) {
 		td->io_issues[ddir]++;
 		td->io_issue_bytes[ddir] += buflen;
+		td->rate_io_issue_bytes[ddir] += buflen;
 	}
 
 	ret = td->io_ops->queue(td, io_u);
@@ -308,6 +309,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
 	if (ret == FIO_Q_BUSY && ddir_rw(ddir)) {
 		td->io_issues[ddir]--;
 		td->io_issue_bytes[ddir] -= buflen;
+		td->rate_io_issue_bytes[ddir] -= buflen;
 	}
 
 	/*
diff --git a/libfio.c b/libfio.c
index b0141a7..d4cad3e 100644
--- a/libfio.c
+++ b/libfio.c
@@ -89,6 +89,8 @@ static void reset_io_counters(struct thread_data *td)
 		td->rate_bytes[ddir] = 0;
 		td->rate_blocks[ddir] = 0;
 		td->bytes_done[ddir] = 0;
+		td->rate_io_issue_bytes[ddir] = 0;
+		td->rate_next_io_time[ddir] = 0;
 	}
 	td->zone_bytes = 0;
 
diff --git a/workqueue.c b/workqueue.c
index 0a6cd20..e236516 100644
--- a/workqueue.c
+++ b/workqueue.c
@@ -124,6 +124,7 @@ int workqueue_enqueue(struct workqueue *wq, struct io_u *io_u)
 		if (ddir_rw(ddir)) {
 			parent->io_issues[ddir]++;
 			parent->io_issue_bytes[ddir] += io_u->xfer_buflen;
+			parent->rate_io_issue_bytes[ddir] += io_u->xfer_buflen;
 		}
 
 		pthread_mutex_lock(&sw->lock);
--
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