Commit 39592d7b authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

bdevperf: parse all available cmdline options



'-s' option (io size) had to be changed to '-o' as it conflicts
with mem-size.

Change-Id: I7486f30ce7d836a6e465e07f723877facb4f8536
Signed-off-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/421736


Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 218fd85d
Loading
Loading
Loading
Loading
+104 −146
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ struct bdevperf_task {
	struct spdk_bdev_io_wait_entry	bdev_io_wait;
};

static const char *g_workload_type;
static int g_io_size = 0;
/* initialize to invalid value so we can detect if user overrides it. */
static int g_rw_percentage = -1;
@@ -71,15 +72,14 @@ static bool g_run_failed = false;
static bool g_shutdown = false;
static uint64_t g_shutdown_tsc;
static bool g_zcopy = true;
static int g_mem_size = 0;
static unsigned g_master_core;
static int g_time_in_sec;
static bool g_mix_specified;

static struct spdk_poller *g_perf_timer = NULL;

static void bdevperf_submit_single(struct io_target *target, struct bdevperf_task *task);

#include "../common.c"

struct io_target {
	char				*name;
	struct spdk_bdev		*bdev;
@@ -582,25 +582,19 @@ bdevperf_submit_on_core(void *arg1, void *arg2)
	}
}

static void usage(char *program_name)
static void
bdevperf_usage(void)
{
	printf("%s options\n", program_name);
	printf("\t[-c configuration file]\n");
	printf("\t[-d memory size in MB]\n");
	printf("\t[-m core mask for distributing I/O submission/completion work\n");
	printf("\t\t(default: 0x1 - use core 0 only)]\n");
	printf("\t[-q io depth]\n");
	printf("\t[-s io size in bytes]\n");
	printf("\t[-w io pattern type, must be one of\n");
	printf("\t\t(read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)]\n");
	printf("\t[-M rwmixread (100 for reads, 0 for writes)]\n");
	printf("\t[-t time in seconds]\n");
	printf("\t[-P Number of moving average period]\n");
	printf(" -q <depth>                io depth\n");
	printf(" -o <size>                 io size in bytes\n");
	printf(" -w <type>                 io pattern type, must be one of (read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)\n");
	printf(" -t <time>                 time in seconds\n");
	printf(" -M <percent>              rwmixread (100 for reads, 0 for writes)\n");
	printf(" -P <num>                  number of moving average period\n");
	printf("\t\t(If set to n, show weighted mean of the previous n IO/s in real time)\n");
	printf("\t\t(Formula: M = 2 / (n + 1), EMA[i+1] = IO/s * M + (1 - M) * EMA[i])\n");
	printf("\t\t(only valid with -S)\n");
	printf("\t[-S Show performance result in real time in seconds]\n");
	spdk_tracelog_usage(stdout, "-L");
	printf(" -S                        show performance result in real time in seconds\n");
}

/*
@@ -821,108 +815,82 @@ spdk_bdevperf_shutdown_cb(void)
	}
}

int
main(int argc, char **argv)
static void
bdevperf_parse_arg(int ch, char *arg)
{
	const char *config_file;
	const char *core_mask;
	const char *workload_type;
	int op;
	bool mix_specified;
	struct spdk_app_opts opts = {};
	int time_in_sec;
	uint64_t show_performance_period_in_usec = 0;
	int rc;
	bool debug_mode = false;

	/* default value */
	config_file = NULL;
	g_queue_depth = 0;
	g_io_size = 0;
	workload_type = NULL;
	time_in_sec = 0;
	mix_specified = false;
	core_mask = NULL;

	while ((op = getopt(argc, argv, "c:d:m:q:s:t:w:L:M:P:S:")) != -1) {
		switch (op) {
		case 'c':
			config_file = optarg;
			break;
		case 'd':
			g_mem_size = atoi(optarg);
			break;
		case 'm':
			core_mask = optarg;
			break;
	switch (ch) {
	case 'q':
		g_queue_depth = atoi(optarg);
		break;
		case 's':
	case 'o':
		g_io_size = atoi(optarg);
		break;
	case 't':
			time_in_sec = atoi(optarg);
		g_time_in_sec = atoi(optarg);
		break;
	case 'w':
			workload_type = optarg;
			break;
		case 'L':
#ifndef DEBUG
			fprintf(stderr, "%s must be built with CONFIG_DEBUG=y for -L flag\n",
				argv[0]);
			usage(argv[0]);
			exit(1);
#else
			rc = spdk_log_set_trace_flag(optarg);
			if (rc < 0) {
				fprintf(stderr, "unknown flag\n");
				usage(argv[0]);
			}

			debug_mode = true;
		g_workload_type = optarg;
		break;
#endif
	case 'M':
		g_rw_percentage = atoi(optarg);
			mix_specified = true;
		g_mix_specified = true;
		break;
	case 'P':
		g_show_performance_ema_period = atoi(optarg);
		break;
	case 'S':
		g_show_performance_real_time = 1;
			show_performance_period_in_usec = atoi(optarg) * 1000000;
		g_show_performance_period_in_usec = atoi(optarg) * 1000000;
		g_show_performance_period_in_usec = spdk_max(g_show_performance_period_in_usec,
							    show_performance_period_in_usec);
						    g_show_performance_period_in_usec);
		break;
		default:
			usage(argv[0]);
			exit(1);
	}
}

	if (!config_file) {
		usage(argv[0]);
		exit(1);
int
main(int argc, char **argv)
{
	struct spdk_app_opts opts = {};
	int rc;

	spdk_app_opts_init(&opts);
	opts.name = "bdevtest";
	opts.config_file = "/usr/local/etc/spdk/iscsi.conf";
	opts.rpc_addr = NULL;
	opts.reactor_mask = NULL;
	opts.mem_size = 1024;
	opts.shutdown_cb = spdk_bdevperf_shutdown_cb;

	/* default value */
	g_queue_depth = 0;
	g_io_size = 0;
	g_workload_type = NULL;
	g_time_in_sec = 0;
	g_mix_specified = false;

	if ((rc = spdk_app_parse_args(argc, argv, &opts, "q:o:t:w:M:P:S:", NULL,
				      bdevperf_parse_arg, bdevperf_usage)) !=
	    SPDK_APP_PARSE_ARGS_SUCCESS) {
		return rc;
	}

	if (g_queue_depth <= 0) {
		usage(argv[0]);
		spdk_app_usage();
		exit(1);
	}
	if (g_io_size <= 0) {
		usage(argv[0]);
		spdk_app_usage();
		exit(1);
	}
	if (!workload_type) {
		usage(argv[0]);
	if (!g_workload_type) {
		spdk_app_usage();
		exit(1);
	}
	if (time_in_sec <= 0) {
		usage(argv[0]);
	if (g_time_in_sec <= 0) {
		spdk_app_usage();
		exit(1);
	}
	g_time_in_usec = time_in_sec * 1000000LL;
	g_time_in_usec = g_time_in_sec * 1000000LL;

	if (g_show_performance_ema_period > 0 &&
	    g_show_performance_real_time == 0) {
@@ -930,74 +898,74 @@ main(int argc, char **argv)
		exit(1);
	}

	if (strcmp(workload_type, "read") &&
	    strcmp(workload_type, "write") &&
	    strcmp(workload_type, "randread") &&
	    strcmp(workload_type, "randwrite") &&
	    strcmp(workload_type, "rw") &&
	    strcmp(workload_type, "randrw") &&
	    strcmp(workload_type, "verify") &&
	    strcmp(workload_type, "reset") &&
	    strcmp(workload_type, "unmap") &&
	    strcmp(workload_type, "flush")) {
	if (strcmp(g_workload_type, "read") &&
	    strcmp(g_workload_type, "write") &&
	    strcmp(g_workload_type, "randread") &&
	    strcmp(g_workload_type, "randwrite") &&
	    strcmp(g_workload_type, "rw") &&
	    strcmp(g_workload_type, "randrw") &&
	    strcmp(g_workload_type, "verify") &&
	    strcmp(g_workload_type, "reset") &&
	    strcmp(g_workload_type, "unmap") &&
	    strcmp(g_workload_type, "flush")) {
		fprintf(stderr,
			"io pattern type must be one of\n"
			"(read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)\n");
		exit(1);
	}

	if (!strcmp(workload_type, "read") ||
	    !strcmp(workload_type, "randread")) {
	if (!strcmp(g_workload_type, "read") ||
	    !strcmp(g_workload_type, "randread")) {
		g_rw_percentage = 100;
	}

	if (!strcmp(workload_type, "write") ||
	    !strcmp(workload_type, "randwrite")) {
	if (!strcmp(g_workload_type, "write") ||
	    !strcmp(g_workload_type, "randwrite")) {
		g_rw_percentage = 0;
	}

	if (!strcmp(workload_type, "unmap")) {
	if (!strcmp(g_workload_type, "unmap")) {
		g_unmap = true;
	}

	if (!strcmp(workload_type, "flush")) {
	if (!strcmp(g_workload_type, "flush")) {
		g_flush = true;
	}

	if (!strcmp(workload_type, "verify") ||
	    !strcmp(workload_type, "reset")) {
	if (!strcmp(g_workload_type, "verify") ||
	    !strcmp(g_workload_type, "reset")) {
		g_rw_percentage = 50;
		if (g_io_size > SPDK_BDEV_LARGE_BUF_MAX_SIZE) {
			fprintf(stderr, "Unable to exceed max I/O size of %d for verify. (%d provided).\n",
				SPDK_BDEV_LARGE_BUF_MAX_SIZE, g_io_size);
			exit(1);
		}
		if (core_mask) {
		if (opts.reactor_mask) {
			fprintf(stderr, "Ignoring -m option. Verify can only run with a single core.\n");
			core_mask = NULL;
			opts.reactor_mask = NULL;
		}
		g_verify = true;
		if (!strcmp(workload_type, "reset")) {
		if (!strcmp(g_workload_type, "reset")) {
			g_reset = true;
		}
	}

	if (!strcmp(workload_type, "read") ||
	    !strcmp(workload_type, "randread") ||
	    !strcmp(workload_type, "write") ||
	    !strcmp(workload_type, "randwrite") ||
	    !strcmp(workload_type, "verify") ||
	    !strcmp(workload_type, "reset") ||
	    !strcmp(workload_type, "unmap") ||
	    !strcmp(workload_type, "flush")) {
		if (mix_specified) {
	if (!strcmp(g_workload_type, "read") ||
	    !strcmp(g_workload_type, "randread") ||
	    !strcmp(g_workload_type, "write") ||
	    !strcmp(g_workload_type, "randwrite") ||
	    !strcmp(g_workload_type, "verify") ||
	    !strcmp(g_workload_type, "reset") ||
	    !strcmp(g_workload_type, "unmap") ||
	    !strcmp(g_workload_type, "flush")) {
		if (g_mix_specified) {
			fprintf(stderr, "Ignoring -M option... Please use -M option"
				" only when using rw or randrw.\n");
		}
	}

	if (!strcmp(workload_type, "rw") ||
	    !strcmp(workload_type, "randrw")) {
	if (!strcmp(g_workload_type, "rw") ||
	    !strcmp(g_workload_type, "randrw")) {
		if (g_rw_percentage < 0 || g_rw_percentage > 100) {
			fprintf(stderr,
				"-M must be specified to value from 0 to 100 "
@@ -1006,12 +974,12 @@ main(int argc, char **argv)
		}
	}

	if (!strcmp(workload_type, "read") ||
	    !strcmp(workload_type, "write") ||
	    !strcmp(workload_type, "rw") ||
	    !strcmp(workload_type, "verify") ||
	    !strcmp(workload_type, "reset") ||
	    !strcmp(workload_type, "unmap")) {
	if (!strcmp(g_workload_type, "read") ||
	    !strcmp(g_workload_type, "write") ||
	    !strcmp(g_workload_type, "rw") ||
	    !strcmp(g_workload_type, "verify") ||
	    !strcmp(g_workload_type, "reset") ||
	    !strcmp(g_workload_type, "unmap")) {
		g_is_random = 0;
	} else {
		g_is_random = 1;
@@ -1024,16 +992,6 @@ main(int argc, char **argv)
		g_zcopy = false;
	}

	bdevtest_init(config_file, core_mask, &opts);
	if (debug_mode) {
		opts.print_level = SPDK_LOG_DEBUG;
	}
	opts.rpc_addr = NULL;
	if (g_mem_size) {
		opts.mem_size = g_mem_size;
	}

	opts.shutdown_cb = spdk_bdevperf_shutdown_cb;
	rc = spdk_app_start(&opts, bdevperf_run, NULL, NULL);
	if (rc) {
		g_run_failed = true;
+2 −2
Original line number Diff line number Diff line
@@ -146,13 +146,13 @@ EOL
$rootdir/scripts/gen_nvme.sh >> $testdir/bdev_gpt.conf

# Run bdevperf with gpt
$testdir/bdevperf/bdevperf -c $testdir/bdev_gpt.conf -q 128 -s 4096 -w verify -t 5
$testdir/bdevperf/bdevperf -c $testdir/bdev_gpt.conf -q 128 -o 4096 -w verify -t 5
rm -f $testdir/bdev_gpt.conf

if [ $RUN_NIGHTLY -eq 1 ]; then
	# Temporarily disabled - infinite loop
	timing_enter reset
	#$testdir/bdevperf/bdevperf -c $testdir/bdev.conf -q 16 -w reset -s 4096 -t 60
	#$testdir/bdevperf/bdevperf -c $testdir/bdev.conf -q 16 -w reset -o 4096 -t 60
	timing_exit reset
	report_test_completion "nightly_bdev_reset"
fi

test/bdev/common.c

deleted100644 → 0
+0 −49
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* This file is included in the bdev test tools, not compiled separately. */

#include "spdk/event.h"

static void
bdevtest_init(const char *config_file, const char *cpumask,
	      struct spdk_app_opts *opts)
{
	assert(opts != NULL);

	spdk_app_opts_init(opts);
	opts->name = "bdevtest";
	opts->config_file = config_file;
	opts->reactor_mask = cpumask;
	opts->mem_size = 1024;
}
+4 −4
Original line number Diff line number Diff line
@@ -42,11 +42,11 @@ trap "killprocess $pid; rm -f $testdir/bdev.conf; exit 1" SIGINT SIGTERM EXIT
cp $testdir/bdev.conf.in $testdir/bdev.conf
echo "[iSCSI_Initiator]" >> $testdir/bdev.conf
echo "  URL iscsi://$TARGET_IP/iqn.2016-06.io.spdk:disk1/0 iSCSI0" >> $testdir/bdev.conf
$rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -s 4096 -w verify -t 5 -d 512
$rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -o 4096 -w verify -t 5 -s 512
if [ $RUN_NIGHTLY -eq 1 ]; then
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -s 4096 -w unmap -t 5 -d 512
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -s 4096 -w flush -t 5 -d 512
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -s 4096 -w reset -t 10 -d 512
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -o 4096 -w unmap -t 5 -s 512
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -o 4096 -w flush -t 5 -s 512
    $rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdev.conf -q 128 -o 4096 -w reset -t 10 -s 512
fi
rm -f $testdir/bdev.conf

+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ $rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:

echo "[Nvme]" > $testdir/bdevperf.conf
echo "  TransportID \"trtype:RDMA adrfam:IPv4 subnqn:nqn.2016-06.io.spdk:cnode1 traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420\" Nvme0" >> $testdir/bdevperf.conf
$rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdevperf.conf -q 128 -s 4096 -w verify -t 1
$rootdir/test/bdev/bdevperf/bdevperf -c $testdir/bdevperf.conf -q 128 -o 4096 -w verify -t 1
sync
rm -rf $testdir/bdevperf.conf
$rpc_py delete_nvmf_subsystem nqn.2016-06.io.spdk:cnode1