Blame SOURCES/0001-Add-option-latency_run-to-continue-enable-latency_ta.patch

86436f
From e1bcd541f63f9029f6c50116831303ad06292edc Mon Sep 17 00:00:00 2001
86436f
From: Song Liu <songliubraving@fb.com>
86436f
Date: Sun, 17 May 2020 22:39:49 -0700
86436f
Subject: [PATCH] Add option latency_run to continue enable latency_target
86436f
86436f
Currently, latency_target run will exist once fio find the highest queue
86436f
depth that meets latency_target. Add option latency_run. If set, fio will
86436f
continue running and try to meet latency_target by adusting queue depth.
86436f
86436f
Signed-off-by: Song Liu <songliubraving@fb.com>
86436f
---
86436f
 HOWTO            |  7 +++++++
86436f
 cconv.c          |  2 ++
86436f
 fio.1            |  5 +++++
86436f
 fio.h            |  1 +
86436f
 io_u.c           | 18 +++++++++++++++++-
86436f
 options.c        | 10 ++++++++++
86436f
 server.h         |  2 +-
86436f
 thread_options.h |  2 ++
86436f
 8 files changed, 45 insertions(+), 2 deletions(-)
86436f
86436f
diff --git a/HOWTO b/HOWTO
86436f
index 430c7b62..f0b4ffe4 100644
86436f
--- a/HOWTO
86436f
+++ b/HOWTO
86436f
@@ -2551,6 +2551,13 @@ I/O latency
86436f
 	defaults to 100.0, meaning that all I/Os must be equal or below to the value
86436f
 	set by :option:`latency_target`.
86436f
 
86436f
+.. option:: latency_run=bool
86436f
+
86436f
+	Used with :option:`latency_target`. If false (default), fio will find
86436f
+	the highest queue depth that meets :option:`latency_target` and exit. If
86436f
+	true, fio will continue running and try to meet :option:`latency_target`
86436f
+	by adjusting queue depth.
86436f
+
86436f
 .. option:: max_latency=time
86436f
 
86436f
 	If set, fio will exit the job with an ETIMEDOUT error if it exceeds this
86436f
diff --git a/cconv.c b/cconv.c
86436f
index 48218dc4..449bcf7b 100644
86436f
--- a/cconv.c
86436f
+++ b/cconv.c
86436f
@@ -288,6 +288,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
86436f
 	o->latency_window = le64_to_cpu(top->latency_window);
86436f
 	o->max_latency = le64_to_cpu(top->max_latency);
86436f
 	o->latency_percentile.u.f = fio_uint64_to_double(le64_to_cpu(top->latency_percentile.u.i));
86436f
+	o->latency_run = le32_to_cpu(top->latency_run);
86436f
 	o->compress_percentage = le32_to_cpu(top->compress_percentage);
86436f
 	o->compress_chunk = le32_to_cpu(top->compress_chunk);
86436f
 	o->dedupe_percentage = le32_to_cpu(top->dedupe_percentage);
86436f
@@ -487,6 +488,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
86436f
 	top->latency_window = __cpu_to_le64(o->latency_window);
86436f
 	top->max_latency = __cpu_to_le64(o->max_latency);
86436f
 	top->latency_percentile.u.i = __cpu_to_le64(fio_double_to_uint64(o->latency_percentile.u.f));
86436f
+	top->latency_run = __cpu_to_le32(o->latency_run);
86436f
 	top->compress_percentage = cpu_to_le32(o->compress_percentage);
86436f
 	top->compress_chunk = cpu_to_le32(o->compress_chunk);
86436f
 	top->dedupe_percentage = cpu_to_le32(o->dedupe_percentage);
86436f
diff --git a/fio.1 b/fio.1
86436f
index a2379f98..3a7a359b 100644
86436f
--- a/fio.1
86436f
+++ b/fio.1
86436f
@@ -2275,6 +2275,11 @@ The percentage of I/Os that must fall within the criteria specified by
86436f
 defaults to 100.0, meaning that all I/Os must be equal or below to the value
86436f
 set by \fBlatency_target\fR.
86436f
 .TP
86436f
+.BI latency_run \fR=\fPbool
86436f
+Used with \fBlatency_target\fR. If false (default), fio will find the highest
86436f
+queue depth that meets \fBlatency_target\fR and exit. If true, fio will continue
86436f
+running and try to meet \fBlatency_target\fR by adjusting queue depth.
86436f
+.TP
86436f
 .BI max_latency \fR=\fPtime
86436f
 If set, fio will exit the job with an ETIMEDOUT error if it exceeds this
86436f
 maximum latency. When the unit is omitted, the value is interpreted in
86436f
diff --git a/fio.h b/fio.h
86436f
index bbf057c1..7610026d 100644
86436f
--- a/fio.h
86436f
+++ b/fio.h
86436f
@@ -377,6 +377,7 @@ struct thread_data {
86436f
 	unsigned int latency_qd_high;
86436f
 	unsigned int latency_qd_low;
86436f
 	unsigned int latency_failed;
86436f
+	unsigned int latency_stable_count;
86436f
 	uint64_t latency_ios;
86436f
 	int latency_end_run;
86436f
 
86436f
diff --git a/io_u.c b/io_u.c
86436f
index aa8808b8..ae1438fd 100644
86436f
--- a/io_u.c
86436f
+++ b/io_u.c
86436f
@@ -1391,6 +1391,7 @@ static bool __lat_target_failed(struct thread_data *td)
86436f
 		td->latency_qd_low--;
86436f
 
86436f
 	td->latency_qd = (td->latency_qd + td->latency_qd_low) / 2;
86436f
+	td->latency_stable_count = 0;
86436f
 
86436f
 	dprint(FD_RATE, "Ramped down: %d %d %d\n", td->latency_qd_low, td->latency_qd, td->latency_qd_high);
86436f
 
86436f
@@ -1440,6 +1441,21 @@ static void lat_target_success(struct thread_data *td)
86436f
 
86436f
 	td->latency_qd_low = td->latency_qd;
86436f
 
86436f
+	if (td->latency_qd + 1 == td->latency_qd_high) {
86436f
+		/*
86436f
+		 * latency_qd will not incease on lat_target_success(), so
86436f
+		 * called stable. If we stick with this queue depth, the
86436f
+		 * final latency is likely lower than latency_target. Fix
86436f
+		 * this by increasing latency_qd_high slowly. Use a naive
86436f
+		 * heuristic here. If we get lat_target_success() 3 times
86436f
+		 * in a row, increase latency_qd_high by 1.
86436f
+		 */
86436f
+		if (++td->latency_stable_count >= 3) {
86436f
+			td->latency_qd_high++;
86436f
+			td->latency_stable_count = 0;
86436f
+		}
86436f
+	}
86436f
+
86436f
 	/*
86436f
 	 * If we haven't failed yet, we double up to a failing value instead
86436f
 	 * of bisecting from highest possible queue depth. If we have set
86436f
@@ -1459,7 +1475,7 @@ static void lat_target_success(struct thread_data *td)
86436f
 	 * Same as last one, we are done. Let it run a latency cycle, so
86436f
 	 * we get only the results from the targeted depth.
86436f
 	 */
86436f
-	if (td->latency_qd == qd) {
86436f
+	if (!o->latency_run && td->latency_qd == qd) {
86436f
 		if (td->latency_end_run) {
86436f
 			dprint(FD_RATE, "We are done\n");
86436f
 			td->done = 1;
86436f
diff --git a/options.c b/options.c
86436f
index b18cea33..da401aed 100644
86436f
--- a/options.c
86436f
+++ b/options.c
86436f
@@ -3672,6 +3672,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
86436f
 		.category = FIO_OPT_C_IO,
86436f
 		.group	= FIO_OPT_G_LATPROF,
86436f
 	},
86436f
+	{
86436f
+		.name	= "latency_run",
86436f
+		.lname	= "Latency Run",
86436f
+		.type	= FIO_OPT_BOOL,
86436f
+		.off1	= offsetof(struct thread_options, latency_run),
86436f
+		.help	= "Keep adjusting queue depth to match latency_target",
86436f
+		.def	= "0",
86436f
+		.category = FIO_OPT_C_IO,
86436f
+		.group	= FIO_OPT_G_LATPROF,
86436f
+	},
86436f
 	{
86436f
 		.name	= "invalidate",
86436f
 		.lname	= "Cache invalidate",
86436f
diff --git a/server.h b/server.h
86436f
index 279b6917..de01a5c8 100644
86436f
--- a/server.h
86436f
+++ b/server.h
86436f
@@ -48,7 +48,7 @@ struct fio_net_cmd_reply {
86436f
 };
86436f
 
86436f
 enum {
86436f
-	FIO_SERVER_VER			= 82,
86436f
+	FIO_SERVER_VER			= 83,
86436f
 
86436f
 	FIO_SERVER_MAX_FRAGMENT_PDU	= 1024,
86436f
 	FIO_SERVER_MAX_CMD_MB		= 2048,
86436f
diff --git a/thread_options.h b/thread_options.h
86436f
index c78ed43d..09ccd5b2 100644
86436f
--- a/thread_options.h
86436f
+++ b/thread_options.h
86436f
@@ -324,6 +324,7 @@ struct thread_options {
86436f
 	unsigned long long latency_target;
86436f
 	unsigned long long latency_window;
86436f
 	fio_fp64_t latency_percentile;
86436f
+	uint32_t latency_run;
86436f
 
86436f
 	unsigned int sig_figs;
86436f
 
86436f
@@ -612,6 +613,7 @@ struct thread_options_pack {
86436f
 	uint64_t latency_window;
86436f
 	uint64_t max_latency;
86436f
 	fio_fp64_t latency_percentile;
86436f
+	uint32_t latency_run;
86436f
 
86436f
 	uint32_t sig_figs;
86436f
 
86436f
-- 
86436f
2.17.0
86436f