xref: /spdk/test/unit/lib/dma/dma.c/dma_ut.c (revision f914cd2e166f37c6b59739c14a6391e3c53feaac)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  */
4 
5 #include "spdk/stdinc.h"
6 #include "spdk_internal/cunit.h"
7 #include "common/lib/test_env.c"
8 #include "unit/lib/json_mock.c"
9 #include "dma/dma.c"
10 
11 static bool g_memory_domain_pull_called;
12 static bool g_memory_domain_push_called;
13 static bool g_memory_domain_translate_called;
14 static bool g_memory_domain_memzero_called;
15 static int g_memory_domain_cb_rc = 123;
16 
17 static void
test_memory_domain_data_cpl_cb(void * ctx,int rc)18 test_memory_domain_data_cpl_cb(void *ctx, int rc)
19 {
20 }
21 
22 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)23 test_memory_domain_pull_data_cb(struct spdk_memory_domain *src_device,
24 				void *src_device_ctx, struct iovec *src_iov, uint32_t src_iovcnt, struct iovec *dst_iov,
25 				uint32_t dst_iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
26 {
27 	g_memory_domain_pull_called = true;
28 
29 	return g_memory_domain_cb_rc;
30 }
31 
32 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)33 test_memory_domain_push_data_cb(struct spdk_memory_domain *dst_domain,
34 				void *dst_domain_ctx,
35 				struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt,
36 				spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
37 {
38 	g_memory_domain_push_called = true;
39 
40 	return g_memory_domain_cb_rc;
41 }
42 
43 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)44 test_memory_domain_translate_memory_cb(struct spdk_memory_domain *src_device, void *src_device_ctx,
45 				       struct spdk_memory_domain *dst_device, struct spdk_memory_domain_translation_ctx *dst_device_ctx,
46 				       void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
47 {
48 	g_memory_domain_translate_called = true;
49 
50 	return g_memory_domain_cb_rc;
51 }
52 
53 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)54 test_memory_domain_memzero_cb(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
55 			      struct iovec *iov, uint32_t iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
56 {
57 	g_memory_domain_memzero_called = true;
58 
59 	return g_memory_domain_cb_rc;
60 }
61 
62 static void
test_dma(void)63 test_dma(void)
64 {
65 	void *test_ibv_pd = (void *)0xdeadbeaf;
66 	struct iovec src_iov = {}, dst_iov = {};
67 	struct spdk_memory_domain *domain = NULL, *domain_2 = NULL, *domain_3 = NULL;
68 	struct spdk_memory_domain *system_domain;
69 	struct spdk_memory_domain_rdma_ctx rdma_ctx = { .ibv_pd = test_ibv_pd };
70 	struct spdk_memory_domain_ctx memory_domain_ctx = { .user_ctx = &rdma_ctx };
71 	struct spdk_memory_domain_ctx *stored_memory_domain_ctx;
72 	struct spdk_memory_domain_translation_result translation_result;
73 	const char *id;
74 	int rc;
75 
76 	system_domain = spdk_memory_domain_get_system_domain();
77 	CU_ASSERT(system_domain != NULL);
78 
79 	/* Create memory domain. No device ptr, expect fail */
80 	rc = spdk_memory_domain_create(NULL, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
81 	CU_ASSERT(rc != 0);
82 
83 	/* Create memory domain. ctx with zero size, expect fail */
84 	memory_domain_ctx.size = 0;
85 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
86 	CU_ASSERT(rc != 0);
87 
88 	/* Create memory domain. expect pass */
89 	memory_domain_ctx.size = sizeof(memory_domain_ctx);
90 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
91 	CU_ASSERT(rc == 0);
92 	SPDK_CU_ASSERT_FATAL(domain != NULL);
93 
94 	/* Get context. Expect pass */
95 	stored_memory_domain_ctx = spdk_memory_domain_get_context(domain);
96 	SPDK_CU_ASSERT_FATAL(stored_memory_domain_ctx != NULL);
97 	CU_ASSERT(stored_memory_domain_ctx->user_ctx == &rdma_ctx);
98 	CU_ASSERT(((struct spdk_memory_domain_rdma_ctx *)stored_memory_domain_ctx->user_ctx)->ibv_pd ==
99 		  rdma_ctx.ibv_pd);
100 
101 	/* Get DMA device type. Expect pass */
102 	CU_ASSERT(spdk_memory_domain_get_dma_device_type(domain) == SPDK_DMA_DEVICE_TYPE_RDMA);
103 
104 	/* Get DMA id. Expect pass */
105 	id = spdk_memory_domain_get_dma_device_id(domain);
106 	CU_ASSERT((!strcmp(id, domain->id)));
107 
108 	/* pull data, callback is NULL. Expect fail */
109 	g_memory_domain_pull_called = false;
110 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
111 					  test_memory_domain_data_cpl_cb, NULL);
112 	CU_ASSERT(rc == -ENOTSUP);
113 	CU_ASSERT(g_memory_domain_pull_called == false);
114 
115 	/* Set pull callback */
116 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
117 
118 	/* pull data. Expect pass */
119 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
120 					  test_memory_domain_data_cpl_cb, NULL);
121 	CU_ASSERT(rc == g_memory_domain_cb_rc);
122 	CU_ASSERT(g_memory_domain_pull_called == true);
123 
124 	/* push data, callback is NULL. Expect fail */
125 	g_memory_domain_push_called = false;
126 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
127 					  test_memory_domain_data_cpl_cb, NULL);
128 	CU_ASSERT(rc == -ENOTSUP);
129 	CU_ASSERT(g_memory_domain_push_called == false);
130 
131 	/* Set push callback */
132 	spdk_memory_domain_set_push(domain, test_memory_domain_push_data_cb);
133 
134 	/* push data. Expect pass */
135 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
136 					  test_memory_domain_data_cpl_cb, NULL);
137 	CU_ASSERT(rc == g_memory_domain_cb_rc);
138 	CU_ASSERT(g_memory_domain_push_called == true);
139 
140 	/* Translate data, callback is NULL. Expect fail */
141 	g_memory_domain_translate_called = false;
142 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
143 					       &translation_result);
144 	CU_ASSERT(rc == -ENOTSUP);
145 	CU_ASSERT(g_memory_domain_translate_called == false);
146 
147 	/* Set translate callback */
148 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
149 
150 	/* Translate data. Expect pass */
151 	g_memory_domain_translate_called = false;
152 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
153 					       &translation_result);
154 	CU_ASSERT(rc == g_memory_domain_cb_rc);
155 	CU_ASSERT(g_memory_domain_translate_called == true);
156 
157 	/* memzero, callback is NULL. Expect fail */
158 	g_memory_domain_memzero_called = false;
159 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
160 	CU_ASSERT(rc == -ENOTSUP);
161 	CU_ASSERT(g_memory_domain_memzero_called == false);
162 
163 	/* Set memzero callback */
164 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
165 
166 	/* memzero. Expect pass */
167 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
168 	CU_ASSERT(rc == g_memory_domain_cb_rc);
169 	CU_ASSERT(g_memory_domain_memzero_called == true);
170 
171 	/* Set translation callback to NULL. Expect pass */
172 	spdk_memory_domain_set_translation(domain, NULL);
173 	CU_ASSERT(domain->translate_cb == NULL);
174 
175 	/* Set translation callback. Expect pass */
176 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
177 	CU_ASSERT(domain->translate_cb == test_memory_domain_translate_memory_cb);
178 
179 	/* Set pull callback to NULL. Expect pass */
180 	spdk_memory_domain_set_pull(domain, NULL);
181 	CU_ASSERT(domain->pull_cb == NULL);
182 
183 	/* Set pull callback. Expect pass */
184 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
185 	CU_ASSERT(domain->pull_cb == test_memory_domain_pull_data_cb);
186 
187 	/* Set memzero to NULL. Expect pass */
188 	spdk_memory_domain_set_memzero(domain, NULL);
189 	CU_ASSERT(domain->memzero_cb == NULL);
190 
191 	/* Set memzero callback. Expect pass */
192 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
193 	CU_ASSERT(domain->memzero_cb == test_memory_domain_memzero_cb);
194 
195 	/* Create 2nd and 3rd memory domains with equal id to test enumeration */
196 	rc = spdk_memory_domain_create(&domain_2, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
197 	CU_ASSERT(rc == 0);
198 
199 	rc = spdk_memory_domain_create(&domain_3, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
200 	CU_ASSERT(rc == 0);
201 
202 	CU_ASSERT(spdk_memory_domain_get_first("test") == domain);
203 	CU_ASSERT(spdk_memory_domain_get_next(domain, "test") == NULL);
204 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == domain_2);
205 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, "test_2") == domain_3);
206 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, "test_2") == NULL);
207 
208 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
209 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
210 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_2);
211 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, NULL) == domain_3);
212 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
213 
214 	/* Remove 2nd device, repeat iteration */
215 	spdk_memory_domain_destroy(domain_2);
216 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
217 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
218 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_3);
219 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
220 
221 	/* Remove 3rd device, repeat iteration */
222 	spdk_memory_domain_destroy(domain_3);
223 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
224 	CU_ASSERT(spdk_memory_domain_get_next(system_domain, NULL) == domain);
225 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == NULL);
226 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == NULL);
227 
228 	/* Destroy memory domain, domain == NULL */
229 	spdk_memory_domain_destroy(NULL);
230 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
231 
232 	/* Destroy memory domain */
233 	spdk_memory_domain_destroy(domain);
234 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == system_domain);
235 }
236 
237 int
main(int argc,char ** argv)238 main(int argc, char **argv)
239 {
240 	CU_pSuite suite = NULL;
241 	unsigned int num_failures;
242 
243 	CU_initialize_registry();
244 
245 	suite = CU_add_suite("dma_suite", NULL, NULL);
246 	CU_ADD_TEST(suite, test_dma);
247 
248 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
249 	CU_cleanup_registry();
250 
251 	return num_failures;
252 }
253