From 012a15837a7f01b9c8dce1e12c23318bde88ec85 Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Mon, 24 Dec 2018 13:20:07 +0800 Subject: [PATCH] nvme/perf: make the drain io in round robin. This patch is used to make the io completion of different ns_ctx owned by each worker in a round robin way. Purpose: To avoid the timeout if there are many ns_ctxes. For example, if each ns_ctxt connects to remote NVMe-oF target with qpair. If there are many qpairs, we may face the time out of some qpairs. Change-Id: I477cb7436dc46ea498a26f990ed79001fa1bf2d6 Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/c/438150 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris --- examples/nvme/perf/perf.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index ef6aa30e8..d96e96e9a 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -787,15 +787,6 @@ submit_io(struct ns_worker_ctx *ns_ctx, int queue_depth) } } -static void -drain_io(struct ns_worker_ctx *ns_ctx) -{ - ns_ctx->is_draining = true; - while (ns_ctx->current_queue_depth > 0) { - check_io(ns_ctx); - } -} - static int init_ns_worker_ctx(struct ns_worker_ctx *ns_ctx) { @@ -854,6 +845,7 @@ work_fn(void *arg) uint64_t tsc_end; struct worker_thread *worker = (struct worker_thread *)arg; struct ns_worker_ctx *ns_ctx = NULL; + uint32_t unfinished_ns_ctx; printf("Starting thread on core %u\n", worker->lcore); @@ -893,12 +885,27 @@ work_fn(void *arg) } } - ns_ctx = worker->ns_ctx; - while (ns_ctx != NULL) { - drain_io(ns_ctx); - cleanup_ns_worker_ctx(ns_ctx); - ns_ctx = ns_ctx->next; - } + /* drain the io of each ns_ctx in round robin to make the fairness */ + do { + unfinished_ns_ctx = 0; + ns_ctx = worker->ns_ctx; + while (ns_ctx != NULL) { + /* first time will enter into this if case */ + if (!ns_ctx->is_draining) { + ns_ctx->is_draining = true; + } + + if (ns_ctx->current_queue_depth > 0) { + check_io(ns_ctx); + if (ns_ctx->current_queue_depth == 0) { + cleanup_ns_worker_ctx(ns_ctx); + } else { + unfinished_ns_ctx++; + } + } + ns_ctx = ns_ctx->next; + } + } while (unfinished_ns_ctx > 0); return 0; }