perf: add number_ios option
normally IOs are submitted until exhausted allocated time new option is additional exit ciriteria provided value represents number of I/O to perform per thread on each namespace, when this condition detected app will print report and exit new io_submitted stat is introduced to prevent submiting more cmds than specified by number_ios and initiate draining it is similar to number_ios fio option Signed-off-by: Jacek Kalwas <jacek.kalwas@intel.com> Change-Id: Icd188c4e3f17abf277d972277834ddf230c38503 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14365 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
This commit is contained in:
parent
3bf8f8a39b
commit
74649fb45a
@ -107,6 +107,7 @@ static const double g_latency_cutoffs[] = {
|
||||
};
|
||||
|
||||
struct ns_worker_stats {
|
||||
uint64_t io_submitted;
|
||||
uint64_t io_completed;
|
||||
uint64_t last_io_completed;
|
||||
uint64_t total_tsc;
|
||||
@ -228,6 +229,7 @@ static uint32_t g_queue_depth;
|
||||
static int g_nr_io_queues_per_ns = 1;
|
||||
static int g_nr_unused_io_queues;
|
||||
static int g_time_in_sec;
|
||||
static uint64_t g_number_ios;
|
||||
static uint64_t g_elapsed_time_in_usec;
|
||||
static int g_warmup_time_in_sec;
|
||||
static uint32_t g_max_completions;
|
||||
@ -1401,6 +1403,8 @@ submit_single_io(struct perf_task *task)
|
||||
struct ns_worker_ctx *ns_ctx = task->ns_ctx;
|
||||
struct ns_entry *entry = ns_ctx->entry;
|
||||
|
||||
assert(!ns_ctx->is_draining);
|
||||
|
||||
if (entry->zipf) {
|
||||
offset_in_ios = spdk_zipf_generate(entry->zipf);
|
||||
} else if (g_is_random) {
|
||||
@ -1431,6 +1435,11 @@ submit_single_io(struct perf_task *task)
|
||||
free(task);
|
||||
} else {
|
||||
ns_ctx->current_queue_depth++;
|
||||
ns_ctx->stats.io_submitted++;
|
||||
}
|
||||
|
||||
if (spdk_unlikely(g_number_ios && ns_ctx->stats.io_submitted >= g_number_ios)) {
|
||||
ns_ctx->is_draining = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1463,10 +1472,10 @@ task_complete(struct perf_task *task)
|
||||
}
|
||||
|
||||
/*
|
||||
* is_draining indicates when time has expired for the test run
|
||||
* and we are just waiting for the previously submitted I/O
|
||||
* to complete. In this case, do not submit a new I/O to replace
|
||||
* the one just completed.
|
||||
* is_draining indicates when time has expired or io_submitted exceeded
|
||||
* g_number_ios for the test run and we are just waiting for the previously
|
||||
* submitted I/O to complete. In this case, do not submit a new I/O to
|
||||
* replace the one just completed.
|
||||
*/
|
||||
if (spdk_unlikely(ns_ctx->is_draining)) {
|
||||
spdk_dma_free(task->iovs[0].iov_base);
|
||||
@ -1649,6 +1658,8 @@ work_fn(void *arg)
|
||||
}
|
||||
|
||||
while (spdk_likely(!g_exit)) {
|
||||
bool all_draining = true;
|
||||
|
||||
/*
|
||||
* Check for completed I/O for each controller. A new
|
||||
* I/O will be submitted in the io_complete callback
|
||||
@ -1664,6 +1675,14 @@ work_fn(void *arg)
|
||||
ns_ctx->stats.idle_tsc += check_now - ns_ctx->stats.last_tsc;
|
||||
}
|
||||
ns_ctx->stats.last_tsc = check_now;
|
||||
|
||||
if (!ns_ctx->is_draining) {
|
||||
all_draining = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (spdk_unlikely(all_draining)) {
|
||||
break;
|
||||
}
|
||||
|
||||
tsc_current = spdk_get_ticks();
|
||||
@ -1762,6 +1781,8 @@ usage(char *program_name)
|
||||
printf("\t[-a, --warmup-time <sec> warmup time in seconds]\n");
|
||||
printf("\t[-c, --core-mask <mask> core mask for I/O submission/completion.]\n");
|
||||
printf("\t\t(default: 1)\n");
|
||||
printf("\t[-d, --number-ios <val> number of I/O to perform per thread on each namespace. Note: this is additional exit criteria.]\n");
|
||||
printf("\t\t(default: 0 - unlimited)\n");
|
||||
printf("\t[-D, --disable-sq-cmb disable submission queue in controller memory buffer, default: enabled]\n");
|
||||
printf("\t[-H, --enable-tcp-hdgst enable header digest for TCP transport, default: disabled]\n");
|
||||
printf("\t[-I, --enable-tcp-ddgst enable data digest for TCP transport, default: disabled]\n");
|
||||
@ -2232,7 +2253,7 @@ parse_metadata(const char *metacfg_str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PERF_GETOPT_SHORT "a:b:c:e:gi:lmo:q:r:k:s:t:w:z:A:C:DF:GHILM:NO:P:Q:RS:T:U:VZ:"
|
||||
#define PERF_GETOPT_SHORT "a:b:c:d:e:gi:lmo:q:r:k:s:t:w:z:A:C:DF:GHILM:NO:P:Q:RS:T:U:VZ:"
|
||||
|
||||
static const struct option g_perf_cmdline_opts[] = {
|
||||
#define PERF_WARMUP_TIME 'a'
|
||||
@ -2263,6 +2284,8 @@ static const struct option g_perf_cmdline_opts[] = {
|
||||
{"hugemem-size", required_argument, NULL, PERF_HUGEMEM_SIZE},
|
||||
#define PERF_TIME 't'
|
||||
{"time", required_argument, NULL, PERF_TIME},
|
||||
#define PERF_NUMBER_IOS 'd'
|
||||
{"number-ios", required_argument, NULL, PERF_NUMBER_IOS},
|
||||
#define PERF_IO_PATTERN 'w'
|
||||
{"io-pattern", required_argument, NULL, PERF_IO_PATTERN},
|
||||
#define PERF_DISABLE_ZCOPY 'z'
|
||||
@ -2334,6 +2357,7 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
|
||||
{
|
||||
int op, long_idx;
|
||||
long int val;
|
||||
long long int val2;
|
||||
int rc;
|
||||
char *endptr;
|
||||
bool ssl_used = false;
|
||||
@ -2420,6 +2444,15 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
|
||||
g_sock_zcopy_threshold = val;
|
||||
}
|
||||
break;
|
||||
case PERF_NUMBER_IOS:
|
||||
val2 = spdk_strtoll(optarg, 10);
|
||||
if (val2 < 0) {
|
||||
fprintf(stderr, "Converting a string to integer failed\n");
|
||||
return val2;
|
||||
}
|
||||
|
||||
g_number_ios = (uint64_t)val2;
|
||||
break;
|
||||
case PERF_ZIPF:
|
||||
errno = 0;
|
||||
g_zipf_theta = strtod(optarg, &endptr);
|
||||
@ -2641,6 +2674,16 @@ parse_args(int argc, char **argv, struct spdk_env_opts *env_opts)
|
||||
perf_set_sock_opts(g_sock_threshold_impl, "zerocopy_threshold", g_sock_zcopy_threshold, NULL);
|
||||
}
|
||||
|
||||
if (g_number_ios && g_warmup_time_in_sec) {
|
||||
fprintf(stderr, "-d (--number-ios) with -a (--warmup-time) is not supported\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_number_ios && g_number_ios < g_queue_depth) {
|
||||
fprintf(stderr, "-d (--number-ios) less than -q (--io-depth) is not supported\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (TAILQ_EMPTY(&g_trid_list)) {
|
||||
/* If no transport IDs specified, default to enumerating all local PCIe devices */
|
||||
add_trid("trtype:PCIe");
|
||||
|
Loading…
Reference in New Issue
Block a user