Commit ef3d6d98 authored by Jim Harris's avatar Jim Harris
Browse files

test/nvme: add histogram to overhead test app



Also add the nvme.sh test script to enable this new histogram
when running the overhead tool.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I825de58362ad631808173a1d3d1b4ccb7df3bcf2

Reviewed-on: https://review.gerrithub.io/365265


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 5044e4f6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ $rootdir/examples/nvme/hello_world/hello_world
timing_exit

timing_enter overhead
$rootdir/test/lib/nvme/overhead/overhead -s 4096 -t 1
$rootdir/test/lib/nvme/overhead/overhead -s 4096 -t 1 -H
timing_exit overhead

PLUGIN_DIR=$rootdir/examples/nvme/fio_plugin
+55 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "spdk/env.h"
#include "spdk/string.h"
#include "spdk/nvme_intel.h"
#include "spdk/histogram_data.h"

#if HAVE_LIBAIO
#include <libaio.h>
@@ -78,6 +79,9 @@ struct ns_entry {
	bool			is_draining;
	uint32_t		current_queue_depth;
	char			name[1024];

	struct spdk_histogram_data	submit_histogram;
	struct spdk_histogram_data	complete_histogram;
};

struct perf_task {
@@ -88,6 +92,8 @@ struct perf_task {
#endif
};

static bool g_enable_histogram = false;

static struct ctrlr_entry *g_ctrlr = NULL;
static struct ns_entry *g_ns = NULL;

@@ -144,6 +150,8 @@ register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
	entry->size_in_ios = spdk_nvme_ns_get_size(ns) /
			     g_io_size_bytes;
	entry->io_size_blocks = g_io_size_bytes / spdk_nvme_ns_get_sector_size(ns);
	spdk_histogram_data_reset(&entry->submit_histogram);
	spdk_histogram_data_reset(&entry->complete_histogram);

	snprintf(entry->name, 44, "%-20.20s (%-20.20s)", cdata->mn, cdata->sn);

@@ -305,6 +313,9 @@ submit_single_io(void)
	if (tsc_submit > g_tsc_submit_max) {
		g_tsc_submit_max = tsc_submit;
	}
	if (g_enable_histogram) {
		spdk_histogram_data_tally(&entry->submit_histogram, tsc_submit);
	}

	if (rc != 0) {
		fprintf(stderr, "starting I/O failed\n");
@@ -357,6 +368,9 @@ check_io(void)
		if (tsc_complete > g_tsc_complete_max) {
			g_tsc_complete_max = tsc_complete;
		}
		if (g_enable_histogram) {
			spdk_histogram_data_tally(&g_ns->complete_histogram, tsc_complete);
		}
		g_io_completed++;
		if (!g_ns->is_draining) {
			submit_single_io();
@@ -466,6 +480,25 @@ static void usage(char *program_name)
	printf("\t[-s io size in bytes]\n");
	printf("\t[-t time in seconds]\n");
	printf("\t\t(default: 1)]\n");
	printf("\t[-H enable histograms]\n");
}

static void
print_bucket(void *ctx, uint64_t start, uint64_t end, uint64_t count,
	     uint64_t total, uint64_t so_far)
{
	double so_far_pct;

	if (count == 0) {
		return;
	}

	so_far_pct = (double)so_far * 100 / total;

	printf("%9.3f - %9.3f: %9.4f%%  (%9ju)\n",
	       (double)start * 1000 * 1000 / g_tsc_rate,
	       (double)end * 1000 * 1000 / g_tsc_rate,
	       so_far_pct, count);
}

static void
@@ -479,6 +512,24 @@ print_stats(void)
	       (float)g_tsc_submit / g_io_completed, g_tsc_submit_min, g_tsc_submit_max);
	printf("complete avg, min, max = %8.1f, %ju, %ju\n",
	       (float)g_tsc_complete / g_io_completed, g_tsc_complete_min, g_tsc_complete_max);

	if (!g_enable_histogram) {
		return;
	}

	printf("\n");
	printf("Submit histogram\n");
	printf("================\n");
	printf("       Range in us     Cumulative     Count\n");
	spdk_histogram_data_iterate(&g_ns->submit_histogram, print_bucket, NULL);
	printf("\n");

	printf("Complete histogram\n");
	printf("==================\n");
	printf("       Range in us     Cumulative     Count\n");
	spdk_histogram_data_iterate(&g_ns->complete_histogram, print_bucket, NULL);
	printf("\n");

}

static int
@@ -490,7 +541,7 @@ parse_args(int argc, char **argv)
	g_io_size_bytes = 0;
	g_time_in_sec = 0;

	while ((op = getopt(argc, argv, "s:t:")) != -1) {
	while ((op = getopt(argc, argv, "s:t:H")) != -1) {
		switch (op) {
		case 's':
			g_io_size_bytes = atoi(optarg);
@@ -498,6 +549,9 @@ parse_args(int argc, char **argv)
		case 't':
			g_time_in_sec = atoi(optarg);
			break;
		case 'H':
			g_enable_histogram = true;
			break;
		default:
			usage(argv[0]);
			return 1;