Commit 381aa0e1 authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Tomasz Zawadzki
Browse files

test/dma: Add option to check specific operation



Add a CLI param "-x" to specify which memory
domain operation must be executed during test

Signed-off-by: default avatarAlexey Marchuk <alexeymar@mellanox.com>
Change-Id: I0dbee8d5d186da1e177e24beadc4e71909e4057f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12344


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 248ccd86
Loading
Loading
Loading
Loading
+90 −9
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ struct dma_test_task {
	struct spdk_thread *thread;
	const char *bdev_name;
	uint64_t num_translations;
	uint64_t num_pull_push;
	uint32_t lcore;

	TAILQ_ENTRY(dma_test_task) link;
@@ -86,6 +87,11 @@ struct dma_test_data_cpl_ctx {
	void *data_cpl_arg;
};

enum dma_test_domain_ops {
	DMA_TEST_DOMAIN_OP_TRANSLATE = 1u << 0,
	DMA_TEST_DOMAIN_OP_PULL_PUSH = 1u << 1,
};

TAILQ_HEAD(, dma_test_task) g_tasks = TAILQ_HEAD_INITIALIZER(g_tasks);

/* User's input */
@@ -96,6 +102,7 @@ static uint32_t g_queue_depth;
static uint32_t g_io_size;
static uint32_t g_run_time_sec;
static uint32_t g_run_count;
static uint32_t g_test_ops;
static bool g_is_random;
static bool g_force_memory_domains_support;

@@ -303,6 +310,7 @@ dma_test_copy_memory(struct dma_test_req *req, struct iovec *dst_iov, uint32_t d
	cpl_ctx->data_cpl_arg = cpl_cb_arg;

	spdk_iovcpy(src_iov, src_iovcnt, dst_iov, dst_iovcnt);
	req->task->num_pull_push++;
	spdk_thread_send_msg(req->task->thread, dma_test_data_cpl, cpl_ctx);

	return 0;
@@ -661,16 +669,48 @@ static int
verify_tasks(void)
{
	struct dma_test_task *task;
	uint64_t total_requests = 0;
	uint64_t num_translations = 0;
	uint64_t num_pull_push = 0;
	int rc = 0;

	if (!g_test_ops) {
		/* No specific ops were requested, nothing to check */
		return rc;
	}

	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;
		total_requests += task->stats.io_completed;
		num_translations += task->num_translations;
		num_pull_push += task->num_pull_push;
	}

	if (g_test_ops & DMA_TEST_DOMAIN_OP_TRANSLATE) {
		if (num_translations == 0) {
			fprintf(stderr, "Requested \"translate\" operation, but it was not executed\n");
			rc = -EINVAL;
		}
	}
	if (g_test_ops & DMA_TEST_DOMAIN_OP_PULL_PUSH) {
		if (num_pull_push == 0) {
			fprintf(stderr, "Requested \"pull_push\" operation, but it was not executed\n");
			rc = -EINVAL;
		}
	}

	return 0;
	/* bdev request can be split, so the total number of pull_push +translate operations
	 * can be bigger than total_number of requests */
	if (num_translations + num_pull_push < total_requests) {
		fprintf(stderr,
			"Operations number mismatch: translate %"PRIu64", pull_push %"PRIu64", expected total %"PRIu64"\n",
			num_translations, num_pull_push, total_requests);
		rc = -EINVAL;
	} else {
		fprintf(stdout, "Total operations: %"PRIu64", translate %"PRIu64" pull_push %"PRIu64"\n",
			total_requests, num_translations, num_pull_push);
	}

	return rc;
}

static void
@@ -746,12 +786,49 @@ static void
print_usage(void)
{
	printf(" -b <bdev>         bdev name for test\n");
	printf(" -f                force memory domains support - abort test if bdev doesn't report memory domains\n");
	printf(" -q <val>          io depth\n");
	printf(" -o <val>          io size in bytes\n");
	printf(" -t <val>          run time in seconds\n");
	printf(" -x <op,op>        Comma separated memory domain operations expected in the test. Values are \"translate\" and \"pull_push\"\n");
	printf(" -w <str>          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
parse_expected_ops(const char *_str)
{
	char *str = strdup(_str);
	char *tok;
	int rc = 0;

	if (!str) {
		fprintf(stderr, "Failed to dup args\n");
		return -ENOMEM;
	}

	tok = strtok(str, ",");
	while (tok) {
		if (strcmp(tok, "translate") == 0) {
			g_test_ops |= DMA_TEST_DOMAIN_OP_TRANSLATE;
		} else if (strcmp(tok, "pull_push") == 0) {
			g_test_ops |= DMA_TEST_DOMAIN_OP_PULL_PUSH;
		} else {
			fprintf(stderr, "Unknown value %s\n", tok);
			rc = -EINVAL;
			break;
		}
		tok = strtok(NULL, ",");
	}

	free(str);

	if (g_test_ops == 0 || rc) {
		fprintf(stderr, "-e \"%s\" specified but nothing was parsed\n", _str);
		return -EINVAL;
	}

	return rc;
}

static int
@@ -794,7 +871,11 @@ parse_arg(int ch, char *arg)
	case 'f':
		g_force_memory_domains_support = true;
		break;

	case 'x':
		if (parse_expected_ops(arg)) {
			return 1;
		}
		break;
	default:
		fprintf(stderr, "Unknown option %c\n", ch);
		return 1;
@@ -860,7 +941,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:fq:o:t:w:M:", NULL, parse_arg, print_usage);
	rc = spdk_app_parse_args(argc, argv, &opts, "b:fq:o:t:x:w:M:", NULL, parse_arg, print_usage);
	if (rc != SPDK_APP_PARSE_ARGS_SUCCESS) {
		exit(rc);
	}
@@ -871,7 +952,7 @@ main(int argc, char **argv)
	}

	rc = spdk_app_start(&opts, dma_test_start, NULL);
	if (rc == 0 && g_force_memory_domains_support) {
	if (rc == 0) {
		rc = verify_tasks();
	}
	destroy_tasks();
+2 −2
Original line number Diff line number Diff line
@@ -69,10 +69,10 @@ $rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode$subsystem -t $TEST

# 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
"$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 -x translate -r /var/tmp/dma.sock

# test data pull/push with split against local malloc
"$rootdir/test/dma/test_dma/test_dma" -q 16 -o 4096 -w randrw -M 70 -t 5 -m 0xc --json <(gen_malloc_json) -b "Malloc0" -r /var/tmp/dma.sock
"$rootdir/test/dma/test_dma/test_dma" -q 16 -o 4096 -w randrw -M 70 -t 5 -m 0xc --json <(gen_malloc_json) -b "Malloc0" -x pull_push -r /var/tmp/dma.sock

trap - SIGINT SIGTERM EXIT