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 *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 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