xref: /spdk/test/unit/lib/dma/dma.c/dma_ut.c (revision 12fbe739a31b09aff0d05f354d4f3bbef99afc55)
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
18 test_memory_domain_data_cpl_cb(void *ctx, int rc)
19 {
20 }
21 
22 static int
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
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
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
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
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_rdma_ctx rdma_ctx = { .ibv_pd = test_ibv_pd };
69 	struct spdk_memory_domain_ctx memory_domain_ctx = { .user_ctx = &rdma_ctx };
70 	struct spdk_memory_domain_ctx *stored_memory_domain_ctx;
71 	struct spdk_memory_domain_translation_result translation_result;
72 	const char *id;
73 	int rc;
74 
75 	/* Create memory domain. No device ptr, expect fail */
76 	rc = spdk_memory_domain_create(NULL, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
77 	CU_ASSERT(rc != 0);
78 
79 	/* Create memory domain. ctx with zero size, expect fail */
80 	memory_domain_ctx.size = 0;
81 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
82 	CU_ASSERT(rc != 0);
83 
84 	/* Create memory domain. expect pass */
85 	memory_domain_ctx.size = sizeof(memory_domain_ctx);
86 	rc = spdk_memory_domain_create(&domain, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test");
87 	CU_ASSERT(rc == 0);
88 	SPDK_CU_ASSERT_FATAL(domain != NULL);
89 
90 	/* Get context. Expect pass */
91 	stored_memory_domain_ctx = spdk_memory_domain_get_context(domain);
92 	SPDK_CU_ASSERT_FATAL(stored_memory_domain_ctx != NULL);
93 	CU_ASSERT(stored_memory_domain_ctx->user_ctx == &rdma_ctx);
94 	CU_ASSERT(((struct spdk_memory_domain_rdma_ctx *)stored_memory_domain_ctx->user_ctx)->ibv_pd ==
95 		  rdma_ctx.ibv_pd);
96 
97 	/* Get DMA device type. Expect pass */
98 	CU_ASSERT(spdk_memory_domain_get_dma_device_type(domain) == SPDK_DMA_DEVICE_TYPE_RDMA);
99 
100 	/* Get DMA id. Expect pass */
101 	id = spdk_memory_domain_get_dma_device_id(domain);
102 	CU_ASSERT((!strcmp(id, domain->id)));
103 
104 	/* pull data, callback is NULL. Expect fail */
105 	g_memory_domain_pull_called = false;
106 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
107 					  test_memory_domain_data_cpl_cb, NULL);
108 	CU_ASSERT(rc == -ENOTSUP);
109 	CU_ASSERT(g_memory_domain_pull_called == false);
110 
111 	/* Set pull callback */
112 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
113 
114 	/* pull data. Expect pass */
115 	rc = spdk_memory_domain_pull_data(domain, NULL, &src_iov, 1, &dst_iov, 1,
116 					  test_memory_domain_data_cpl_cb, NULL);
117 	CU_ASSERT(rc == g_memory_domain_cb_rc);
118 	CU_ASSERT(g_memory_domain_pull_called == true);
119 
120 	/* push data, callback is NULL. Expect fail */
121 	g_memory_domain_push_called = false;
122 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
123 					  test_memory_domain_data_cpl_cb, NULL);
124 	CU_ASSERT(rc == -ENOTSUP);
125 	CU_ASSERT(g_memory_domain_push_called == false);
126 
127 	/* Set push callback */
128 	spdk_memory_domain_set_push(domain, test_memory_domain_push_data_cb);
129 
130 	/* push data. Expect pass */
131 	rc = spdk_memory_domain_push_data(domain, NULL, &dst_iov, 1, &src_iov, 1,
132 					  test_memory_domain_data_cpl_cb, NULL);
133 	CU_ASSERT(rc == g_memory_domain_cb_rc);
134 	CU_ASSERT(g_memory_domain_push_called == true);
135 
136 	/* Translate data, callback is NULL. Expect fail */
137 	g_memory_domain_translate_called = false;
138 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
139 					       &translation_result);
140 	CU_ASSERT(rc == -ENOTSUP);
141 	CU_ASSERT(g_memory_domain_translate_called == false);
142 
143 	/* Set translate callback */
144 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
145 
146 	/* Translate data. Expect pass */
147 	g_memory_domain_translate_called = false;
148 	rc = spdk_memory_domain_translate_data(domain, NULL, domain, NULL, (void *)0xfeeddbeef, 0x1000,
149 					       &translation_result);
150 	CU_ASSERT(rc == g_memory_domain_cb_rc);
151 	CU_ASSERT(g_memory_domain_translate_called == true);
152 
153 	/* memzero, callback is NULL. Expect fail */
154 	g_memory_domain_memzero_called = false;
155 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
156 	CU_ASSERT(rc == -ENOTSUP);
157 	CU_ASSERT(g_memory_domain_memzero_called == false);
158 
159 	/* Set memzero callback */
160 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
161 
162 	/* memzero. Expect pass */
163 	rc = spdk_memory_domain_memzero(domain, NULL, &src_iov, 1, test_memory_domain_data_cpl_cb, NULL);
164 	CU_ASSERT(rc == g_memory_domain_cb_rc);
165 	CU_ASSERT(g_memory_domain_memzero_called == true);
166 
167 	/* Set translation callback to NULL. Expect pass */
168 	spdk_memory_domain_set_translation(domain, NULL);
169 	CU_ASSERT(domain->translate_cb == NULL);
170 
171 	/* Set translation callback. Expect pass */
172 	spdk_memory_domain_set_translation(domain, test_memory_domain_translate_memory_cb);
173 	CU_ASSERT(domain->translate_cb == test_memory_domain_translate_memory_cb);
174 
175 	/* Set pull callback to NULL. Expect pass */
176 	spdk_memory_domain_set_pull(domain, NULL);
177 	CU_ASSERT(domain->pull_cb == NULL);
178 
179 	/* Set pull callback. Expect pass */
180 	spdk_memory_domain_set_pull(domain, test_memory_domain_pull_data_cb);
181 	CU_ASSERT(domain->pull_cb == test_memory_domain_pull_data_cb);
182 
183 	/* Set memzero to NULL. Expect pass */
184 	spdk_memory_domain_set_memzero(domain, NULL);
185 	CU_ASSERT(domain->memzero_cb == NULL);
186 
187 	/* Set memzero callback. Expect pass */
188 	spdk_memory_domain_set_memzero(domain, test_memory_domain_memzero_cb);
189 	CU_ASSERT(domain->memzero_cb == test_memory_domain_memzero_cb);
190 
191 	/* Create 2nd and 3rd memory domains with equal id to test enumeration */
192 	rc = spdk_memory_domain_create(&domain_2, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
193 	CU_ASSERT(rc == 0);
194 
195 	rc = spdk_memory_domain_create(&domain_3, SPDK_DMA_DEVICE_TYPE_RDMA, &memory_domain_ctx, "test_2");
196 	CU_ASSERT(rc == 0);
197 
198 	CU_ASSERT(spdk_memory_domain_get_first("test") == domain);
199 	CU_ASSERT(spdk_memory_domain_get_next(domain, "test") == NULL);
200 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == domain_2);
201 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, "test_2") == domain_3);
202 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, "test_2") == NULL);
203 
204 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == domain);
205 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_2);
206 	CU_ASSERT(spdk_memory_domain_get_next(domain_2, NULL) == domain_3);
207 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
208 
209 	/* Remove 2nd device, repeat iteration */
210 	spdk_memory_domain_destroy(domain_2);
211 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == domain);
212 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == domain_3);
213 	CU_ASSERT(spdk_memory_domain_get_next(domain_3, NULL) == NULL);
214 
215 	/* Remove 3rd device, repeat iteration */
216 	spdk_memory_domain_destroy(domain_3);
217 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == domain);
218 	CU_ASSERT(spdk_memory_domain_get_next(domain, NULL) == NULL);
219 	CU_ASSERT(spdk_memory_domain_get_first("test_2") == NULL);
220 
221 	/* Destroy memory domain, domain == NULL */
222 	spdk_memory_domain_destroy(NULL);
223 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == domain);
224 
225 	/* Destroy memory domain */
226 	spdk_memory_domain_destroy(domain);
227 	CU_ASSERT(spdk_memory_domain_get_first(NULL) == NULL);
228 }
229 
230 int
231 main(int argc, char **argv)
232 {
233 	CU_pSuite suite = NULL;
234 	unsigned int num_failures;
235 
236 	CU_initialize_registry();
237 
238 	suite = CU_add_suite("dma_suite", NULL, NULL);
239 	CU_ADD_TEST(suite, test_dma);
240 
241 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
242 	CU_cleanup_registry();
243 
244 	return num_failures;
245 }
246