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

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