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