xref: /spdk/test/unit/lib/dma/dma.c/dma_ut.c (revision f914cd2e166f37c6b59739c14a6391e3c53feaac)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
24e527910SAlexey Marchuk  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
34e527910SAlexey Marchuk  */
44e527910SAlexey Marchuk 
54e527910SAlexey Marchuk #include "spdk/stdinc.h"
6ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
74e527910SAlexey Marchuk #include "common/lib/test_env.c"
84e527910SAlexey Marchuk #include "unit/lib/json_mock.c"
94e527910SAlexey Marchuk #include "dma/dma.c"
104e527910SAlexey Marchuk 
119efad746SAlexey Marchuk static bool g_memory_domain_pull_called;
120ecbe09bSAlexey Marchuk static bool g_memory_domain_push_called;
134e527910SAlexey Marchuk static bool g_memory_domain_translate_called;
145fd9561fSAlexey Marchuk static bool g_memory_domain_memzero_called;
154e527910SAlexey Marchuk static int g_memory_domain_cb_rc = 123;
164e527910SAlexey Marchuk 
174e527910SAlexey Marchuk static void
test_memory_domain_data_cpl_cb(void * ctx,int rc)180ecbe09bSAlexey Marchuk test_memory_domain_data_cpl_cb(void *ctx, int rc)
194e527910SAlexey Marchuk {
204e527910SAlexey Marchuk }
214e527910SAlexey Marchuk 
225fd9561fSAlexey Marchuk static int
test_memory_domain_pull_data_cb(struct spdk_memory_domain * src_device,void * src_device_ctx,struct iovec * src_iov,uint32_t src_iovcnt,struct iovec * dst_iov,uint32_t dst_iovcnt,spdk_memory_domain_data_cpl_cb cpl_cb,void * cpl_cb_arg)235fd9561fSAlexey Marchuk test_memory_domain_pull_data_cb(struct spdk_memory_domain *src_device,
244e527910SAlexey Marchuk 				void *src_device_ctx, struct iovec *src_iov, uint32_t src_iovcnt, struct iovec *dst_iov,
250ecbe09bSAlexey Marchuk 				uint32_t dst_iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
264e527910SAlexey Marchuk {
279efad746SAlexey Marchuk 	g_memory_domain_pull_called = true;
284e527910SAlexey Marchuk 
294e527910SAlexey Marchuk 	return g_memory_domain_cb_rc;
304e527910SAlexey Marchuk }
314e527910SAlexey Marchuk 
325fd9561fSAlexey Marchuk static int
test_memory_domain_push_data_cb(struct spdk_memory_domain * dst_domain,void * dst_domain_ctx,struct iovec * dst_iov,uint32_t dst_iovcnt,struct iovec * src_iov,uint32_t src_iovcnt,spdk_memory_domain_data_cpl_cb cpl_cb,void * cpl_cb_arg)335fd9561fSAlexey Marchuk test_memory_domain_push_data_cb(struct spdk_memory_domain *dst_domain,
340ecbe09bSAlexey Marchuk 				void *dst_domain_ctx,
350ecbe09bSAlexey Marchuk 				struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt,
360ecbe09bSAlexey Marchuk 				spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
370ecbe09bSAlexey Marchuk {
380ecbe09bSAlexey Marchuk 	g_memory_domain_push_called = true;
390ecbe09bSAlexey Marchuk 
400ecbe09bSAlexey Marchuk 	return g_memory_domain_cb_rc;
410ecbe09bSAlexey Marchuk }
420ecbe09bSAlexey Marchuk 
434e527910SAlexey Marchuk static int
test_memory_domain_translate_memory_cb(struct spdk_memory_domain * src_device,void * src_device_ctx,struct spdk_memory_domain * dst_device,struct spdk_memory_domain_translation_ctx * dst_device_ctx,void * addr,size_t len,struct spdk_memory_domain_translation_result * result)444e527910SAlexey Marchuk test_memory_domain_translate_memory_cb(struct spdk_memory_domain *src_device, void *src_device_ctx,
454e527910SAlexey Marchuk 				       struct spdk_memory_domain *dst_device, struct spdk_memory_domain_translation_ctx *dst_device_ctx,
464e527910SAlexey Marchuk 				       void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
474e527910SAlexey Marchuk {
484e527910SAlexey Marchuk 	g_memory_domain_translate_called = true;
494e527910SAlexey Marchuk 
504e527910SAlexey Marchuk 	return g_memory_domain_cb_rc;
514e527910SAlexey Marchuk }
524e527910SAlexey Marchuk 
535fd9561fSAlexey Marchuk static int
test_memory_domain_memzero_cb(struct spdk_memory_domain * src_domain,void * src_domain_ctx,struct iovec * iov,uint32_t iovcnt,spdk_memory_domain_data_cpl_cb cpl_cb,void * cpl_cb_arg)545fd9561fSAlexey Marchuk test_memory_domain_memzero_cb(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
555fd9561fSAlexey Marchuk 			      struct iovec *iov, uint32_t iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
565fd9561fSAlexey Marchuk {
575fd9561fSAlexey Marchuk 	g_memory_domain_memzero_called = true;
585fd9561fSAlexey Marchuk 
595fd9561fSAlexey Marchuk 	return g_memory_domain_cb_rc;
605fd9561fSAlexey Marchuk }
615fd9561fSAlexey Marchuk 
624e527910SAlexey Marchuk static void
test_dma(void)634e527910SAlexey Marchuk test_dma(void)
644e527910SAlexey Marchuk {
654e527910SAlexey Marchuk 	void *test_ibv_pd = (void *)0xdeadbeaf;
664e527910SAlexey Marchuk 	struct iovec src_iov = {}, dst_iov = {};
674e527910SAlexey Marchuk 	struct spdk_memory_domain *domain = NULL, *domain_2 = NULL, *domain_3 = NULL;
68*f914cd2eSJacek Kalwas 	struct spdk_memory_domain *system_domain;
69549bcdc0SAlexey Marchuk 	struct spdk_memory_domain_rdma_ctx rdma_ctx = { .ibv_pd = test_ibv_pd };
70549bcdc0SAlexey Marchuk 	struct spdk_memory_domain_ctx memory_domain_ctx = { .user_ctx = &rdma_ctx };
714e527910SAlexey Marchuk 	struct spdk_memory_domain_ctx *stored_memory_domain_ctx;
724e527910SAlexey Marchuk 	struct spdk_memory_domain_translation_result translation_result;
734e527910SAlexey Marchuk 	const char *id;
744e527910SAlexey Marchuk 	int rc;
754e527910SAlexey Marchuk 
76*f914cd2eSJacek Kalwas 	system_domain = spdk_memory_domain_get_system_domain();
77*f914cd2eSJacek Kalwas 	CU_ASSERT(system_domain != NULL);
78*f914cd2eSJacek Kalwas 
794e527910SAlexey Marchuk 	/* Create memory domain. No device ptr, expect fail */
804e527910SAlexey Marchuk 	rc = spdk_memory_domain_create(NULL, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
814e527910SAlexey Marchuk 	CU_ASSERT(rc != 0);
824e527910SAlexey Marchuk 
834e527910SAlexey Marchuk 	/* Create memory domain. ctx with zero size, expect fail */
844e527910SAlexey Marchuk 	memory_domain_ctx.size = 0;
854e527910SAlexey Marchuk 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
864e527910SAlexey Marchuk 	CU_ASSERT(rc != 0);
874e527910SAlexey Marchuk 
884e527910SAlexey Marchuk 	/* Create memory domain. expect pass */
894e527910SAlexey Marchuk 	memory_domain_ctx.size = sizeof(memory_domain_ctx);
904e527910SAlexey Marchuk 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
914e527910SAlexey Marchuk 	CU_ASSERT(rc == 0);
924e527910SAlexey Marchuk 	SPDK_CU_ASSERT_FATAL(domain != NULL);
934e527910SAlexey Marchuk 
944e527910SAlexey Marchuk 	/* Get context. Expect pass */
954e527910SAlexey Marchuk 	stored_memory_domain_ctx = spdk_memory_domain_get_context(domain);
964e527910SAlexey Marchuk 	SPDK_CU_ASSERT_FATAL(stored_memory_domain_ctx != NULL);
97549bcdc0SAlexey Marchuk 	CU_ASSERT(stored_memory_domain_ctx->user_ctx == &rdma_ctx);
98549bcdc0SAlexey Marchuk 	CU_ASSERT(((struct spdk_memory_domain_rdma_ctx *)stored_memory_domain_ctx->user_ctx)->ibv_pd ==
99549bcdc0SAlexey Marchuk 		  rdma_ctx.ibv_pd);
1004e527910SAlexey Marchuk 
1014e527910SAlexey Marchuk 	/* Get DMA device type. Expect pass */
1024e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_dma_device_type(domain) == SPDK_DMA_DEVICE_TYPE_RDMA);
1034e527910SAlexey Marchuk 
1044e527910SAlexey Marchuk 	/* Get DMA id. Expect pass */
1054e527910SAlexey Marchuk 	id = spdk_memory_domain_get_dma_device_id(domain);
1064e527910SAlexey Marchuk 	CU_ASSERT((!strcmp(id, domain->id)));
1074e527910SAlexey Marchuk 
1089efad746SAlexey Marchuk 	/* pull data, callback is NULL. Expect fail */
1099efad746SAlexey Marchuk 	g_memory_domain_pull_called = false;
1109efad746SAlexey Marchuk 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
1110ecbe09bSAlexey Marchuk 					  test_memory_domain_data_cpl_cb, NULL);
1124e527910SAlexey Marchuk 	CU_ASSERT(rc == -ENOTSUP);
1139efad746SAlexey Marchuk 	CU_ASSERT(g_memory_domain_pull_called == false);
1144e527910SAlexey Marchuk 
1159efad746SAlexey Marchuk 	/* Set pull callback */
1169efad746SAlexey Marchuk 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
1174e527910SAlexey Marchuk 
1189efad746SAlexey Marchuk 	/* pull data. Expect pass */
1199efad746SAlexey Marchuk 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
1200ecbe09bSAlexey Marchuk 					  test_memory_domain_data_cpl_cb, NULL);
1214e527910SAlexey Marchuk 	CU_ASSERT(rc == g_memory_domain_cb_rc);
1229efad746SAlexey Marchuk 	CU_ASSERT(g_memory_domain_pull_called == true);
1234e527910SAlexey Marchuk 
1240ecbe09bSAlexey Marchuk 	/* push data, callback is NULL. Expect fail */
1250ecbe09bSAlexey Marchuk 	g_memory_domain_push_called = false;
1260ecbe09bSAlexey Marchuk 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
1270ecbe09bSAlexey Marchuk 					  test_memory_domain_data_cpl_cb, NULL);
1280ecbe09bSAlexey Marchuk 	CU_ASSERT(rc == -ENOTSUP);
1290ecbe09bSAlexey Marchuk 	CU_ASSERT(g_memory_domain_push_called == false);
1300ecbe09bSAlexey Marchuk 
1310ecbe09bSAlexey Marchuk 	/* Set push callback */
1320ecbe09bSAlexey Marchuk 	spdk_memory_domain_set_push(domain, test_memory_domain_push_data_cb);
1330ecbe09bSAlexey Marchuk 
1340ecbe09bSAlexey Marchuk 	/* push data. Expect pass */
1350ecbe09bSAlexey Marchuk 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
1360ecbe09bSAlexey Marchuk 					  test_memory_domain_data_cpl_cb, NULL);
1370ecbe09bSAlexey Marchuk 	CU_ASSERT(rc == g_memory_domain_cb_rc);
1380ecbe09bSAlexey Marchuk 	CU_ASSERT(g_memory_domain_push_called == true);
1390ecbe09bSAlexey Marchuk 
1404e527910SAlexey Marchuk 	/* Translate data, callback is NULL. Expect fail */
1414e527910SAlexey Marchuk 	g_memory_domain_translate_called = false;
1424e527910SAlexey Marchuk 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
1434e527910SAlexey Marchuk 					       &translation_result);
1444e527910SAlexey Marchuk 	CU_ASSERT(rc == -ENOTSUP);
1454e527910SAlexey Marchuk 	CU_ASSERT(g_memory_domain_translate_called == false);
1464e527910SAlexey Marchuk 
1474e527910SAlexey Marchuk 	/* Set translate callback */
1484e527910SAlexey Marchuk 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
1494e527910SAlexey Marchuk 
1504e527910SAlexey Marchuk 	/* Translate data. Expect pass */
1514e527910SAlexey Marchuk 	g_memory_domain_translate_called = false;
1524e527910SAlexey Marchuk 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
1534e527910SAlexey Marchuk 					       &translation_result);
1544e527910SAlexey Marchuk 	CU_ASSERT(rc == g_memory_domain_cb_rc);
1554e527910SAlexey Marchuk 	CU_ASSERT(g_memory_domain_translate_called == true);
1564e527910SAlexey Marchuk 
1575fd9561fSAlexey Marchuk 	/* memzero, callback is NULL. Expect fail */
1585fd9561fSAlexey Marchuk 	g_memory_domain_memzero_called = false;
1595fd9561fSAlexey Marchuk 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
1605fd9561fSAlexey Marchuk 	CU_ASSERT(rc == -ENOTSUP);
1615fd9561fSAlexey Marchuk 	CU_ASSERT(g_memory_domain_memzero_called == false);
1625fd9561fSAlexey Marchuk 
1635fd9561fSAlexey Marchuk 	/* Set memzero callback */
1645fd9561fSAlexey Marchuk 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
1655fd9561fSAlexey Marchuk 
1665fd9561fSAlexey Marchuk 	/* memzero. Expect pass */
1675fd9561fSAlexey Marchuk 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
1685fd9561fSAlexey Marchuk 	CU_ASSERT(rc == g_memory_domain_cb_rc);
1695fd9561fSAlexey Marchuk 	CU_ASSERT(g_memory_domain_memzero_called == true);
1705fd9561fSAlexey Marchuk 
1714e527910SAlexey Marchuk 	/* Set translation callback to NULL. Expect pass */
1724e527910SAlexey Marchuk 	spdk_memory_domain_set_translation(domain, NULL);
1734e527910SAlexey Marchuk 	CU_ASSERT(domain->translate_cb == NULL);
1744e527910SAlexey Marchuk 
1754e527910SAlexey Marchuk 	/* Set translation callback. Expect pass */
1764e527910SAlexey Marchuk 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
1774e527910SAlexey Marchuk 	CU_ASSERT(domain->translate_cb == test_memory_domain_translate_memory_cb);
1784e527910SAlexey Marchuk 
1799efad746SAlexey Marchuk 	/* Set pull callback to NULL. Expect pass */
1809efad746SAlexey Marchuk 	spdk_memory_domain_set_pull(domain, NULL);
1819efad746SAlexey Marchuk 	CU_ASSERT(domain->pull_cb == NULL);
1824e527910SAlexey Marchuk 
1835fd9561fSAlexey Marchuk 	/* Set pull callback. Expect pass */
1849efad746SAlexey Marchuk 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
1859efad746SAlexey Marchuk 	CU_ASSERT(domain->pull_cb == test_memory_domain_pull_data_cb);
1864e527910SAlexey Marchuk 
1875fd9561fSAlexey Marchuk 	/* Set memzero to NULL. Expect pass */
1885fd9561fSAlexey Marchuk 	spdk_memory_domain_set_memzero(domain, NULL);
1895fd9561fSAlexey Marchuk 	CU_ASSERT(domain->memzero_cb == NULL);
1905fd9561fSAlexey Marchuk 
1915fd9561fSAlexey Marchuk 	/* Set memzero callback. Expect pass */
1925fd9561fSAlexey Marchuk 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
1935fd9561fSAlexey Marchuk 	CU_ASSERT(domain->memzero_cb == test_memory_domain_memzero_cb);
1945fd9561fSAlexey Marchuk 
1954e527910SAlexey Marchuk 	/* Create 2nd and 3rd memory domains with equal id to test enumeration */
1964e527910SAlexey Marchuk 	rc = spdk_memory_domain_create(&domain_2, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
1974e527910SAlexey Marchuk 	CU_ASSERT(rc == 0);
1984e527910SAlexey Marchuk 
1994e527910SAlexey Marchuk 	rc = spdk_memory_domain_create(&domain_3, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
2004e527910SAlexey Marchuk 	CU_ASSERT(rc == 0);
2014e527910SAlexey Marchuk 
2024e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_first("test") == domain);
2034e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain, "test") == NULL);
2044e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == domain_2);
2054e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, "test_2") == domain_3);
2064e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, "test_2") == NULL);
2074e527910SAlexey Marchuk 
208*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
209*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
2104e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_2);
2114e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, NULL) == domain_3);
2124e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
2134e527910SAlexey Marchuk 
2144e527910SAlexey Marchuk 	/* Remove 2nd device, repeat iteration */
2154e527910SAlexey Marchuk 	spdk_memory_domain_destroy(domain_2);
216*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
217*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
2184e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_3);
2194e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
2204e527910SAlexey Marchuk 
2214e527910SAlexey Marchuk 	/* Remove 3rd device, repeat iteration */
2224e527910SAlexey Marchuk 	spdk_memory_domain_destroy(domain_3);
223*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
224*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
2254e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == NULL);
2264e527910SAlexey Marchuk 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == NULL);
2274e527910SAlexey Marchuk 
2284e527910SAlexey Marchuk 	/* Destroy memory domain, domain == NULL */
2294e527910SAlexey Marchuk 	spdk_memory_domain_destroy(NULL);
230*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
2314e527910SAlexey Marchuk 
2324e527910SAlexey Marchuk 	/* Destroy memory domain */
2334e527910SAlexey Marchuk 	spdk_memory_domain_destroy(domain);
234*f914cd2eSJacek Kalwas 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
2354e527910SAlexey Marchuk }
2364e527910SAlexey Marchuk 
2374e527910SAlexey Marchuk int
main(int argc,char ** argv)2384e527910SAlexey Marchuk main(int argc, char **argv)
2394e527910SAlexey Marchuk {
2404e527910SAlexey Marchuk 	CU_pSuite suite = NULL;
2414e527910SAlexey Marchuk 	unsigned int num_failures;
2424e527910SAlexey Marchuk 
2434e527910SAlexey Marchuk 	CU_initialize_registry();
2444e527910SAlexey Marchuk 
2454e527910SAlexey Marchuk 	suite = CU_add_suite("dma_suite", NULL, NULL);
2464e527910SAlexey Marchuk 	CU_ADD_TEST(suite, test_dma);
2474e527910SAlexey Marchuk 
248ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
2494e527910SAlexey Marchuk 	CU_cleanup_registry();
2504e527910SAlexey Marchuk 
2514e527910SAlexey Marchuk 	return num_failures;
2524e527910SAlexey Marchuk }
253