From 94a10ad2eab2b65223a12f00c1a28fa61d28514a Mon Sep 17 00:00:00 2001 From: Alexey Marchuk Date: Tue, 1 Feb 2022 10:49:08 +0300 Subject: [PATCH] test/dma: Add option to fail test if memory domains are not supported That will be used to test memory domains with logical volumes, we need to make sure that lvol correctly reports memory domains. Also add a counter for the number of translation_cb calls and verify that it is not smaller than the total number of completed IO requests Signed-off-by: Alexey Marchuk Change-Id: I42f0cb14fd24c95de830146a603de64f1a8848be Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11374 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Tested-by: SPDK CI Jenkins --- test/dma/test_dma/test_dma.c | 34 ++++++++++++++++++++++++++++++++-- test/nvmf/host/dma.sh | 8 +++----- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/test/dma/test_dma/test_dma.c b/test/dma/test_dma/test_dma.c index 243ec6b7d..6119ac6e5 100644 --- a/test/dma/test_dma/test_dma.c +++ b/test/dma/test_dma/test_dma.c @@ -75,6 +75,7 @@ struct dma_test_task { struct dma_test_req *reqs; struct spdk_thread *thread; const char *bdev_name; + uint64_t num_translations; uint32_t lcore; TAILQ_ENTRY(dma_test_task) link; @@ -91,6 +92,7 @@ static uint32_t g_io_size; static uint32_t g_run_time_sec; static uint32_t g_run_count; static bool g_is_random; +static bool g_force_memory_domains_support; static struct spdk_thread *g_main_thread; static struct spdk_poller *g_runtime_poller; @@ -297,6 +299,8 @@ dma_test_translate_memory_cb(struct spdk_memory_domain *src_domain, void *src_do result->rdma.rkey = req->mr->rkey; result->dst_domain = dst_domain; + req->task->num_translations++; + return 0; } @@ -599,6 +603,22 @@ destroy_tasks(void) } } +static int +verify_tasks(void) +{ + struct dma_test_task *task; + + TAILQ_FOREACH(task, &g_tasks, link) { + if (task->num_translations < task->stats.io_completed) { + fprintf(stderr, "Unexpected number of translations %"PRIu64", must be at least %"PRIu64"\n", + task->num_translations, task->stats.io_completed); + return -1; + } + } + + return 0; +} + static void dma_test_start(void *arg) { @@ -615,7 +635,10 @@ dma_test_start(void *arg) return; } bdev = spdk_bdev_desc_get_bdev(desc); - if (!dma_test_check_bdev_supports_rdma_memory_domain(bdev)) { + /* This function checks if bdev supports memory domains. Test is not failed if there are + * no memory domains since bdev layer can pull/push data */ + if (!dma_test_check_bdev_supports_rdma_memory_domain(bdev) && g_force_memory_domains_support) { + fprintf(stderr, "Test aborted due to \"-f\" (force memory domains support) option\n"); spdk_bdev_close(desc); spdk_app_stop(-ENODEV); return; @@ -672,6 +695,7 @@ print_usage(void) printf(" -t run time in seconds\n"); printf(" -w io pattern (read, write, randread, randwrite, randrw)\n"); printf(" -M <0-100> rw percentage (100 for reads, 0 for writes)\n"); + printf(" -f force memory domains support - abort test if bdev doesn't report memory domains\n"); } static int @@ -711,6 +735,9 @@ parse_arg(int ch, char *arg) case 'b': g_bdev_name = arg; break; + case 'f': + g_force_memory_domains_support = true; + break; default: fprintf(stderr, "Unknown option %c\n", ch); @@ -777,7 +804,7 @@ main(int argc, char **argv) opts.name = "test_dma"; opts.shutdown_cb = dma_test_shutdown_cb; - rc = spdk_app_parse_args(argc, argv, &opts, "b:q:o:t:w:M:", NULL, parse_arg, print_usage); + rc = spdk_app_parse_args(argc, argv, &opts, "b:fq:o:t:w:M:", NULL, parse_arg, print_usage); if (rc != SPDK_APP_PARSE_ARGS_SUCCESS) { exit(rc); } @@ -788,6 +815,9 @@ main(int argc, char **argv) } rc = spdk_app_start(&opts, dma_test_start, NULL); + if (rc == 0 && g_force_memory_domains_support) { + rc = verify_tasks(); + } destroy_tasks(); spdk_app_fini(); diff --git a/test/nvmf/host/dma.sh b/test/nvmf/host/dma.sh index 55ff5f5eb..7597a66e3 100755 --- a/test/nvmf/host/dma.sh +++ b/test/nvmf/host/dma.sh @@ -23,11 +23,9 @@ $rpc_py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode$subsystem -a -s SPDK0000 $rpc_py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode$subsystem Malloc0 $rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode$subsystem -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -"$rootdir/test/dma/test_dma/test_dma" -q 16 -o 4096 -w randrw -M 70 -t 5 -m 0xc --json <(gen_nvmf_target_json $subsystem) -b "Nvme${subsystem}n1" -test_dmapid=$! - -wait $test_dmapid -sync +# test memory translation +# test_dma doesn't use RPC, but we change the sock path since nvmf target is already using the default RPC sock +"$rootdir/test/dma/test_dma/test_dma" -q 16 -o 4096 -w randrw -M 70 -t 5 -m 0xc --json <(gen_nvmf_target_json $subsystem) -b "Nvme${subsystem}n1" -f -r /var/tmp/dma.sock trap - SIGINT SIGTERM EXIT