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