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: Dariusz 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: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
218fd85dc1
commit
39592d7b20
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bdevperf_parse_arg(int ch, char *arg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'q':
|
||||
g_queue_depth = atoi(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
g_io_size = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
g_time_in_sec = atoi(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
g_workload_type = optarg;
|
||||
break;
|
||||
case 'M':
|
||||
g_rw_percentage = atoi(optarg);
|
||||
g_mix_specified = true;
|
||||
break;
|
||||
case 'P':
|
||||
g_show_performance_ema_period = atoi(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
g_show_performance_real_time = 1;
|
||||
g_show_performance_period_in_usec = atoi(optarg) * 1000000;
|
||||
g_show_performance_period_in_usec = spdk_max(g_show_performance_period_in_usec,
|
||||
g_show_performance_period_in_usec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
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;
|
||||
|
||||
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 */
|
||||
config_file = NULL;
|
||||
g_queue_depth = 0;
|
||||
g_io_size = 0;
|
||||
workload_type = NULL;
|
||||
time_in_sec = 0;
|
||||
mix_specified = false;
|
||||
core_mask = NULL;
|
||||
g_workload_type = NULL;
|
||||
g_time_in_sec = 0;
|
||||
g_mix_specified = false;
|
||||
|
||||
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;
|
||||
case 'q':
|
||||
g_queue_depth = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
g_io_size = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
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;
|
||||
break;
|
||||
#endif
|
||||
case 'M':
|
||||
g_rw_percentage = atoi(optarg);
|
||||
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 = spdk_max(g_show_performance_period_in_usec,
|
||||
show_performance_period_in_usec);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
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 (!config_file) {
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -1,49 +0,0 @@
|
||||
/*-
|
||||
* 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;
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user