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