Commit b482eda0 authored by Evgeniy Kochetov's avatar Evgeniy Kochetov Committed by Tomasz Zawadzki
Browse files

nvme/perf: Basic synchronization of workers



Currently, NVMe perf worker starts IO and measurements as soon as all
its QPs were connected. But other workers may still be connecting and
not started their measurements yet. With large number of QPs when
connections take a long time this can cause inaccurate performance
reporting.

This patch adds synchronization point for workers after all QPs were
connected and before start of IO and measurements.

Signed-off-by: default avatarEvgeniy Kochetov <evgeniik@nvidia.com>
Change-Id: If0c9be8dd41c8e851aae6b3e71afa3efe5314330
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5126


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 1bc2a2d9
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ static int g_num_namespaces;
static TAILQ_HEAD(, worker_thread) g_workers = TAILQ_HEAD_INITIALIZER(g_workers);
static int g_num_workers = 0;
static uint32_t g_main_core;
static pthread_barrier_t g_worker_sync_barrier;

static uint64_t g_tsc_rate;

@@ -1280,15 +1281,24 @@ work_fn(void *arg)
	struct ns_worker_ctx *ns_ctx = NULL;
	uint32_t unfinished_ns_ctx;
	bool warmup = false;
	int rc;

	/* Allocate queue pairs for each namespace. */
	TAILQ_FOREACH(ns_ctx, &worker->ns_ctx, link) {
		if (init_ns_worker_ctx(ns_ctx) != 0) {
			printf("ERROR: init_ns_worker_ctx() failed\n");
			/* Wait on barrier to avoid blocking of successful workers */
			pthread_barrier_wait(&g_worker_sync_barrier);
			return 1;
		}
	}

	rc = pthread_barrier_wait(&g_worker_sync_barrier);
	if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
		printf("ERROR: failed to wait on thread sync barrier\n");
		return 1;
	}

	tsc_current = spdk_get_ticks();
	tsc_next_print = tsc_current + g_tsc_rate;

@@ -2382,6 +2392,12 @@ int main(int argc, char **argv)
		goto cleanup;
	}

	rc = pthread_barrier_init(&g_worker_sync_barrier, NULL, g_num_workers);
	if (rc != 0) {
		fprintf(stderr, "Unable to initialize thread sync barrier\n");
		goto cleanup;
	}

	printf("Initialization complete. Launching workers.\n");

	/* Launch all of the secondary workers */
@@ -2404,6 +2420,7 @@ int main(int argc, char **argv)
	print_stats();

cleanup:
	pthread_barrier_destroy(&g_worker_sync_barrier);
	if (thread_id && pthread_cancel(thread_id) == 0) {
		pthread_join(thread_id, NULL);
	}