perf: Add option to create unused io queue pairs

For some testing, we need queue pairs to exist but not actually
be in use.

Change-Id: I2b17ff0172c9ec002692babcf7d4d612c3062eb4
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/392977
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Ben Walker 2017-12-26 11:40:00 -07:00
parent 8aa0e50f1a
commit 24d5087441

View File

@ -51,6 +51,9 @@
struct ctrlr_entry { struct ctrlr_entry {
struct spdk_nvme_ctrlr *ctrlr; struct spdk_nvme_ctrlr *ctrlr;
struct spdk_nvme_intel_rw_latency_page *latency_page; struct spdk_nvme_intel_rw_latency_page *latency_page;
struct spdk_nvme_qpair **unused_qpairs;
struct ctrlr_entry *next; struct ctrlr_entry *next;
char name[1024]; char name[1024];
}; };
@ -177,6 +180,7 @@ static int g_rw_percentage;
static int g_is_random; static int g_is_random;
static int g_queue_depth; static int g_queue_depth;
static int g_nr_io_queues_per_ns = 1; static int g_nr_io_queues_per_ns = 1;
static int g_nr_unused_io_queues = 0;
static int g_time_in_sec; static int g_time_in_sec;
static uint32_t g_max_completions; static uint32_t g_max_completions;
static int g_dpdk_mem; static int g_dpdk_mem;
@ -362,6 +366,26 @@ register_ctrlr(struct spdk_nvme_ctrlr *ctrlr)
register_ns(ctrlr, ns); register_ns(ctrlr, ns);
} }
if (g_nr_unused_io_queues) {
int i;
printf("Creating %u unused qpairs for controller %s\n", g_nr_unused_io_queues, entry->name);
entry->unused_qpairs = calloc(g_nr_unused_io_queues, sizeof(struct spdk_nvme_qpair *));
if (!entry->unused_qpairs) {
fprintf(stderr, "Unable to allocate memory for qpair array\n");
exit(1);
}
for (i = 0; i < g_nr_unused_io_queues; i++) {
entry->unused_qpairs[i] = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, NULL, 0);
if (!entry->unused_qpairs[i]) {
fprintf(stderr, "Unable to allocate unused qpair. Did you request too many?\n");
exit(1);
}
}
}
} }
#if HAVE_LIBAIO #if HAVE_LIBAIO
@ -936,6 +960,7 @@ static void usage(char *program_name)
printf("\t[-q io depth]\n"); printf("\t[-q io depth]\n");
printf("\t[-s io size in bytes]\n"); printf("\t[-s io size in bytes]\n");
printf("\t[-n number of io queues per namespace. default: 1]\n"); printf("\t[-n number of io queues per namespace. default: 1]\n");
printf("\t[-U number of unused io queues per controller. default: 0]\n");
printf("\t[-w io pattern type, must be one of\n"); printf("\t[-w io pattern type, must be one of\n");
printf("\t\t(read, write, randread, randwrite, rw, randrw)]\n"); printf("\t\t(read, write, randread, randwrite, rw, randrw)]\n");
printf("\t[-M rwmixread (100 for reads, 0 for writes)]\n"); printf("\t[-M rwmixread (100 for reads, 0 for writes)]\n");
@ -1275,7 +1300,7 @@ parse_args(int argc, char **argv)
g_core_mask = NULL; g_core_mask = NULL;
g_max_completions = 0; g_max_completions = 0;
while ((op = getopt(argc, argv, "c:d:e:i:lm:n:q:r:s:t:w:DLM:")) != -1) { while ((op = getopt(argc, argv, "c:d:e:i:lm:n:q:r:s:t:w:DLM:U:")) != -1) {
switch (op) { switch (op) {
case 'c': case 'c':
g_core_mask = optarg; g_core_mask = optarg;
@ -1329,6 +1354,9 @@ parse_args(int argc, char **argv)
g_rw_percentage = atoi(optarg); g_rw_percentage = atoi(optarg);
mix_specified = true; mix_specified = true;
break; break;
case 'U':
g_nr_unused_io_queues = atoi(optarg);
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
@ -1564,6 +1592,17 @@ unregister_controllers(void)
spdk_nvme_ctrlr_is_feature_supported(entry->ctrlr, SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING)) { spdk_nvme_ctrlr_is_feature_supported(entry->ctrlr, SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING)) {
set_latency_tracking_feature(entry->ctrlr, false); set_latency_tracking_feature(entry->ctrlr, false);
} }
if (g_nr_unused_io_queues) {
int i;
for (i = 0; i < g_nr_unused_io_queues; i++) {
spdk_nvme_ctrlr_free_io_qpair(entry->unused_qpairs[i]);
}
free(entry->unused_qpairs);
}
spdk_nvme_detach(entry->ctrlr); spdk_nvme_detach(entry->ctrlr);
free(entry); free(entry);
entry = next; entry = next;