1b5f360c4SShuhei Matsumoto /* SPDX-License-Identifier: BSD-3-Clause
2b5f360c4SShuhei Matsumoto * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3b5f360c4SShuhei Matsumoto */
4b5f360c4SShuhei Matsumoto
5b5f360c4SShuhei Matsumoto #include "spdk/stdinc.h"
6ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
7b5f360c4SShuhei Matsumoto #include "spdk_internal/mock.h"
8b5f360c4SShuhei Matsumoto #include "common/lib/test_env.c"
98a01b4d6SAlexey Marchuk #include "rdma_utils/rdma_utils.c"
10b5f360c4SShuhei Matsumoto
11b5f360c4SShuhei Matsumoto DEFINE_STUB(spdk_mem_map_alloc, struct spdk_mem_map *, (uint64_t default_translation,
12b5f360c4SShuhei Matsumoto const struct spdk_mem_map_ops *ops, void *cb_ctx), NULL);
13b5f360c4SShuhei Matsumoto DEFINE_STUB_V(spdk_mem_map_free, (struct spdk_mem_map **pmap));
14b5f360c4SShuhei Matsumoto DEFINE_STUB(spdk_mem_map_set_translation, int, (struct spdk_mem_map *map, uint64_t vaddr,
15b5f360c4SShuhei Matsumoto uint64_t size, uint64_t translation), 0);
16b5f360c4SShuhei Matsumoto DEFINE_STUB(spdk_mem_map_clear_translation, int, (struct spdk_mem_map *map, uint64_t vaddr,
17b5f360c4SShuhei Matsumoto uint64_t size), 0);
18b5f360c4SShuhei Matsumoto DEFINE_STUB(spdk_mem_map_translate, uint64_t, (const struct spdk_mem_map *map, uint64_t vaddr,
19b5f360c4SShuhei Matsumoto uint64_t *size), 0);
20*0a9c0239SAlexey Marchuk DEFINE_STUB(spdk_memory_domain_create, int, (struct spdk_memory_domain **_domain,
21*0a9c0239SAlexey Marchuk enum spdk_dma_device_type type,
22*0a9c0239SAlexey Marchuk struct spdk_memory_domain_ctx *ctx, const char *id), 0);
23*0a9c0239SAlexey Marchuk DEFINE_STUB_V(spdk_memory_domain_destroy, (struct spdk_memory_domain *domain));
24b5f360c4SShuhei Matsumoto
25b5f360c4SShuhei Matsumoto struct ut_rdma_device {
26b5f360c4SShuhei Matsumoto struct ibv_context *context;
27b5f360c4SShuhei Matsumoto bool removed;
28b5f360c4SShuhei Matsumoto TAILQ_ENTRY(ut_rdma_device) tailq;
29b5f360c4SShuhei Matsumoto };
30b5f360c4SShuhei Matsumoto
31b5f360c4SShuhei Matsumoto static TAILQ_HEAD(, ut_rdma_device) g_ut_dev_list = TAILQ_HEAD_INITIALIZER(g_ut_dev_list);
32b5f360c4SShuhei Matsumoto
33b5f360c4SShuhei Matsumoto struct ibv_context **
rdma_get_devices(int * num_devices)34b5f360c4SShuhei Matsumoto rdma_get_devices(int *num_devices)
35b5f360c4SShuhei Matsumoto {
36b5f360c4SShuhei Matsumoto struct ibv_context **ctx_list;
37b5f360c4SShuhei Matsumoto struct ut_rdma_device *ut_dev;
38b5f360c4SShuhei Matsumoto int num_ut_devs = 0;
39b5f360c4SShuhei Matsumoto int i = 0;
40b5f360c4SShuhei Matsumoto
41b5f360c4SShuhei Matsumoto TAILQ_FOREACH(ut_dev, &g_ut_dev_list, tailq) {
42b5f360c4SShuhei Matsumoto if (!ut_dev->removed) {
43b5f360c4SShuhei Matsumoto num_ut_devs++;
44b5f360c4SShuhei Matsumoto }
45b5f360c4SShuhei Matsumoto }
46b5f360c4SShuhei Matsumoto
47b5f360c4SShuhei Matsumoto ctx_list = malloc(sizeof(*ctx_list) * (num_ut_devs + 1));
48b5f360c4SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(ctx_list);
49b5f360c4SShuhei Matsumoto
50b5f360c4SShuhei Matsumoto TAILQ_FOREACH(ut_dev, &g_ut_dev_list, tailq) {
51b5f360c4SShuhei Matsumoto if (!ut_dev->removed) {
52b5f360c4SShuhei Matsumoto ctx_list[i++] = ut_dev->context;
53b5f360c4SShuhei Matsumoto }
54b5f360c4SShuhei Matsumoto }
55b5f360c4SShuhei Matsumoto ctx_list[i] = NULL;
56b5f360c4SShuhei Matsumoto
57b5f360c4SShuhei Matsumoto if (num_devices) {
58b5f360c4SShuhei Matsumoto *num_devices = num_ut_devs;
59b5f360c4SShuhei Matsumoto }
60b5f360c4SShuhei Matsumoto
61b5f360c4SShuhei Matsumoto return ctx_list;
62b5f360c4SShuhei Matsumoto }
63b5f360c4SShuhei Matsumoto
64b5f360c4SShuhei Matsumoto void
rdma_free_devices(struct ibv_context ** list)65b5f360c4SShuhei Matsumoto rdma_free_devices(struct ibv_context **list)
66b5f360c4SShuhei Matsumoto {
67b5f360c4SShuhei Matsumoto free(list);
68b5f360c4SShuhei Matsumoto }
69b5f360c4SShuhei Matsumoto
70b5f360c4SShuhei Matsumoto struct ibv_pd *
ibv_alloc_pd(struct ibv_context * context)71b5f360c4SShuhei Matsumoto ibv_alloc_pd(struct ibv_context *context)
72b5f360c4SShuhei Matsumoto {
73b5f360c4SShuhei Matsumoto struct ibv_pd *pd;
74b5f360c4SShuhei Matsumoto struct ut_rdma_device *ut_dev;
75b5f360c4SShuhei Matsumoto
76b5f360c4SShuhei Matsumoto TAILQ_FOREACH(ut_dev, &g_ut_dev_list, tailq) {
77b5f360c4SShuhei Matsumoto if (ut_dev->context == context && !ut_dev->removed) {
78b5f360c4SShuhei Matsumoto break;
79b5f360c4SShuhei Matsumoto }
80b5f360c4SShuhei Matsumoto }
81b5f360c4SShuhei Matsumoto
82b5f360c4SShuhei Matsumoto if (!ut_dev) {
83b5f360c4SShuhei Matsumoto return NULL;
84b5f360c4SShuhei Matsumoto }
85b5f360c4SShuhei Matsumoto
86b5f360c4SShuhei Matsumoto pd = calloc(1, sizeof(*pd));
87b5f360c4SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(pd);
88b5f360c4SShuhei Matsumoto
89b5f360c4SShuhei Matsumoto pd->context = context;
90b5f360c4SShuhei Matsumoto
91b5f360c4SShuhei Matsumoto return pd;
92b5f360c4SShuhei Matsumoto }
93b5f360c4SShuhei Matsumoto
94b5f360c4SShuhei Matsumoto int
ibv_dealloc_pd(struct ibv_pd * pd)95b5f360c4SShuhei Matsumoto ibv_dealloc_pd(struct ibv_pd *pd)
96b5f360c4SShuhei Matsumoto {
97b5f360c4SShuhei Matsumoto free(pd);
98b5f360c4SShuhei Matsumoto
99b5f360c4SShuhei Matsumoto return 0;
100b5f360c4SShuhei Matsumoto }
101b5f360c4SShuhei Matsumoto
102b5f360c4SShuhei Matsumoto static struct ut_rdma_device *
ut_rdma_add_dev(struct ibv_context * context)103b5f360c4SShuhei Matsumoto ut_rdma_add_dev(struct ibv_context *context)
104b5f360c4SShuhei Matsumoto {
105b5f360c4SShuhei Matsumoto struct ut_rdma_device *ut_dev;
106b5f360c4SShuhei Matsumoto
107b5f360c4SShuhei Matsumoto ut_dev = calloc(1, sizeof(*ut_dev));
108b5f360c4SShuhei Matsumoto if (!ut_dev) {
109b5f360c4SShuhei Matsumoto return NULL;
110b5f360c4SShuhei Matsumoto }
111b5f360c4SShuhei Matsumoto
112b5f360c4SShuhei Matsumoto ut_dev->context = context;
113b5f360c4SShuhei Matsumoto TAILQ_INSERT_TAIL(&g_ut_dev_list, ut_dev, tailq);
114b5f360c4SShuhei Matsumoto
115b5f360c4SShuhei Matsumoto return ut_dev;
116b5f360c4SShuhei Matsumoto }
117b5f360c4SShuhei Matsumoto
118b5f360c4SShuhei Matsumoto static void
ut_rdma_remove_dev(struct ut_rdma_device * ut_dev)119b5f360c4SShuhei Matsumoto ut_rdma_remove_dev(struct ut_rdma_device *ut_dev)
120b5f360c4SShuhei Matsumoto {
121b5f360c4SShuhei Matsumoto TAILQ_REMOVE(&g_ut_dev_list, ut_dev, tailq);
122b5f360c4SShuhei Matsumoto free(ut_dev);
123b5f360c4SShuhei Matsumoto }
124b5f360c4SShuhei Matsumoto
1258a01b4d6SAlexey Marchuk static struct rdma_utils_device *
_rdma_get_dev(struct ibv_context * context)126b5f360c4SShuhei Matsumoto _rdma_get_dev(struct ibv_context *context)
127b5f360c4SShuhei Matsumoto {
1288a01b4d6SAlexey Marchuk struct rdma_utils_device *dev;
129b5f360c4SShuhei Matsumoto
130b5f360c4SShuhei Matsumoto TAILQ_FOREACH(dev, &g_dev_list, tailq) {
131b5f360c4SShuhei Matsumoto if (dev->context == context) {
132b5f360c4SShuhei Matsumoto break;
133b5f360c4SShuhei Matsumoto }
134b5f360c4SShuhei Matsumoto }
135b5f360c4SShuhei Matsumoto
136b5f360c4SShuhei Matsumoto return dev;
137b5f360c4SShuhei Matsumoto }
138b5f360c4SShuhei Matsumoto
139b5f360c4SShuhei Matsumoto static void
test_spdk_rdma_pd(void)140b5f360c4SShuhei Matsumoto test_spdk_rdma_pd(void)
141b5f360c4SShuhei Matsumoto {
142b5f360c4SShuhei Matsumoto struct ut_rdma_device *ut_dev0, *ut_dev1, *ut_dev2;
143b5f360c4SShuhei Matsumoto struct ibv_pd *pd1, *pd1_1, *pd2;
144b5f360c4SShuhei Matsumoto
145b5f360c4SShuhei Matsumoto ut_dev0 = ut_rdma_add_dev((struct ibv_context *)0xface);
146b5f360c4SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(ut_dev0 != NULL);
147b5f360c4SShuhei Matsumoto
148b5f360c4SShuhei Matsumoto ut_dev1 = ut_rdma_add_dev((struct ibv_context *)0xc0ffee);
149b5f360c4SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(ut_dev1 != NULL);
150b5f360c4SShuhei Matsumoto
151b5f360c4SShuhei Matsumoto ut_dev2 = ut_rdma_add_dev((struct ibv_context *)0xf00d);
152b5f360c4SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(ut_dev2 != NULL);
153b5f360c4SShuhei Matsumoto
154b5f360c4SShuhei Matsumoto /* There are ut_dev0 and ut_dev1. */
155b5f360c4SShuhei Matsumoto ut_dev2->removed = true;
156b5f360c4SShuhei Matsumoto
157b5f360c4SShuhei Matsumoto /* Call spdk_rdma_get_pd() to non-existent ut_dev2. */
1588a01b4d6SAlexey Marchuk pd2 = spdk_rdma_utils_get_pd(ut_dev2->context);
159b5f360c4SShuhei Matsumoto
1608a01b4d6SAlexey Marchuk /* Then, spdk_rdma_utils_get_pd() should return NULL and g_dev_list should have dev0 and dev1. */
161b5f360c4SShuhei Matsumoto CU_ASSERT(pd2 == NULL);
162b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev0->context) != NULL);
163b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev1->context) != NULL);
164b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev2->context) == NULL);
165b5f360c4SShuhei Matsumoto
166b5f360c4SShuhei Matsumoto /* Remove ut_dev0 and add ut_dev2. */
167b5f360c4SShuhei Matsumoto ut_dev0->removed = true;
168b5f360c4SShuhei Matsumoto ut_dev2->removed = false;
169b5f360c4SShuhei Matsumoto
1708a01b4d6SAlexey Marchuk /* Call spdk_rdma_utils_get_pd() to ut_dev1. */
1718a01b4d6SAlexey Marchuk pd1 = spdk_rdma_utils_get_pd(ut_dev1->context);
172b5f360c4SShuhei Matsumoto
1738a01b4d6SAlexey Marchuk /* Then, spdk_rdma_utils_get_pd() should return pd1 and g_dev_list should have dev1 and dev2. */
174b5f360c4SShuhei Matsumoto CU_ASSERT(pd1 != NULL);
175b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev0->context) == NULL);
176b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev1->context) != NULL);
177b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev2->context) != NULL);
178b5f360c4SShuhei Matsumoto
179b5f360c4SShuhei Matsumoto /* Remove ut_dev1. */
180b5f360c4SShuhei Matsumoto ut_dev1->removed = true;
181b5f360c4SShuhei Matsumoto
1828a01b4d6SAlexey Marchuk /* Call spdk_rdma_utils_get_pd() again to ut_dev1 which does not exist anymore. */
1838a01b4d6SAlexey Marchuk pd1_1 = spdk_rdma_utils_get_pd(ut_dev1->context);
184b5f360c4SShuhei Matsumoto
1858a01b4d6SAlexey Marchuk /* Then, spdk_rdma_utils_get_pd() should return NULL and g_dev_list should still have dev1. */
186b5f360c4SShuhei Matsumoto CU_ASSERT(pd1_1 == NULL);
187b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev0->context) == NULL);
188b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev1->context) != NULL);
189b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev2->context) != NULL);
190b5f360c4SShuhei Matsumoto
1918a01b4d6SAlexey Marchuk /* Call spdk_rdma_utils_put_pd() to pd1. */
1928a01b4d6SAlexey Marchuk spdk_rdma_utils_put_pd(pd1);
193b5f360c4SShuhei Matsumoto
194b5f360c4SShuhei Matsumoto /* Then, dev1 should be removed from g_dev_list. */
195b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev0->context) == NULL);
196b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev1->context) == NULL);
197b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev2->context) != NULL);
198b5f360c4SShuhei Matsumoto
1998a01b4d6SAlexey Marchuk /* Call spdk_rdma_utils_get_pd() to ut_dev2. */
2008a01b4d6SAlexey Marchuk pd2 = spdk_rdma_utils_get_pd(ut_dev2->context);
201b5f360c4SShuhei Matsumoto
2028a01b4d6SAlexey Marchuk /* spdk_rdma_utils_get_pd() should succeed and g_dev_list should still have dev2
2038a01b4d6SAlexey Marchuk * even after spdk_rdma_utils_put_pd() is called to pd2.
204b5f360c4SShuhei Matsumoto */
205b5f360c4SShuhei Matsumoto CU_ASSERT(pd2 != NULL);
206b5f360c4SShuhei Matsumoto
2078a01b4d6SAlexey Marchuk spdk_rdma_utils_put_pd(pd2);
208b5f360c4SShuhei Matsumoto
209b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev0->context) == NULL);
210b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev1->context) == NULL);
211b5f360c4SShuhei Matsumoto CU_ASSERT(_rdma_get_dev(ut_dev2->context) != NULL);
212b5f360c4SShuhei Matsumoto
2138a01b4d6SAlexey Marchuk _rdma_utils_fini();
214b5f360c4SShuhei Matsumoto
215b5f360c4SShuhei Matsumoto ut_rdma_remove_dev(ut_dev0);
216b5f360c4SShuhei Matsumoto ut_rdma_remove_dev(ut_dev1);
217b5f360c4SShuhei Matsumoto ut_rdma_remove_dev(ut_dev2);
218b5f360c4SShuhei Matsumoto }
219b5f360c4SShuhei Matsumoto
220b5f360c4SShuhei Matsumoto int
main(int argc,char ** argv)221b5f360c4SShuhei Matsumoto main(int argc, char **argv)
222b5f360c4SShuhei Matsumoto {
223b5f360c4SShuhei Matsumoto CU_pSuite suite = NULL;
224b5f360c4SShuhei Matsumoto unsigned int num_failures;
225b5f360c4SShuhei Matsumoto
226b5f360c4SShuhei Matsumoto CU_initialize_registry();
227b5f360c4SShuhei Matsumoto
228b5f360c4SShuhei Matsumoto suite = CU_add_suite("rdma_common", NULL, NULL);
229b5f360c4SShuhei Matsumoto CU_ADD_TEST(suite, test_spdk_rdma_pd);
230b5f360c4SShuhei Matsumoto
231ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL);
232b5f360c4SShuhei Matsumoto CU_cleanup_registry();
233b5f360c4SShuhei Matsumoto return num_failures;
234b5f360c4SShuhei Matsumoto }
235