xref: /spdk/test/unit/lib/accel/accel.c/accel_ut.c (revision 877573897ad52be4fa8989f7617bd655b87e05c4)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2021 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk_cunit.h"
8 #include "spdk_internal/mock.h"
9 #include "spdk_internal/accel_module.h"
10 #include "thread/thread_internal.h"
11 #include "common/lib/test_env.c"
12 #include "accel/accel.c"
13 #include "accel/accel_sw.c"
14 #include "unit/lib/json_mock.c"
15 
16 #ifdef SPDK_CONFIG_PMDK
17 DEFINE_STUB(pmem_msync, int, (const void *addr, size_t len), 0);
18 DEFINE_STUB(pmem_memcpy_persist, void *, (void *pmemdest, const void *src, size_t len), NULL);
19 DEFINE_STUB(pmem_is_pmem, int, (const void *addr, size_t len), 0);
20 DEFINE_STUB(pmem_memset_persist, void *, (void *pmemdest, int c, size_t len), NULL);
21 #endif
22 
23 /* global vars and setup/cleanup functions used for all test functions */
24 struct spdk_accel_module_if g_module = {};
25 struct spdk_io_channel *g_ch = NULL;
26 struct accel_io_channel *g_accel_ch = NULL;
27 struct sw_accel_io_channel *g_sw_ch = NULL;
28 struct spdk_io_channel *g_module_ch = NULL;
29 
30 static uint64_t g_opc_mask = 0;
31 
32 static uint64_t
33 _accel_op_to_bit(enum accel_opcode opc)
34 {
35 	return (1 << opc);
36 }
37 
38 static bool
39 _supports_opcode(enum accel_opcode opc)
40 {
41 	if (_accel_op_to_bit(opc) & g_opc_mask) {
42 		return true;
43 	}
44 	return false;
45 }
46 
47 static int
48 test_setup(void)
49 {
50 	int i;
51 
52 	g_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct accel_io_channel));
53 	if (g_ch == NULL) {
54 		/* for some reason the assert fatal macro doesn't work in the setup function. */
55 		CU_ASSERT(false);
56 		return -1;
57 	}
58 	g_accel_ch = (struct accel_io_channel *)((char *)g_ch + sizeof(struct spdk_io_channel));
59 	g_module_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct sw_accel_io_channel));
60 	if (g_module_ch == NULL) {
61 		CU_ASSERT(false);
62 		return -1;
63 	}
64 
65 	g_module.submit_tasks = sw_accel_submit_tasks;
66 	g_module.name = "software";
67 	for (i = 0; i < ACCEL_OPC_LAST; i++) {
68 		g_accel_ch->module_ch[i] = g_module_ch;
69 		g_modules_opc[i] = &g_module;
70 	}
71 	g_sw_ch = (struct sw_accel_io_channel *)((char *)g_module_ch + sizeof(
72 				struct spdk_io_channel));
73 	TAILQ_INIT(&g_sw_ch->tasks_to_complete);
74 	g_module.supports_opcode = _supports_opcode;
75 	return 0;
76 }
77 
78 static int
79 test_cleanup(void)
80 {
81 	free(g_ch);
82 	free(g_module_ch);
83 
84 	return 0;
85 }
86 
87 #define DUMMY_ARG 0xDEADBEEF
88 static bool g_dummy_cb_called = false;
89 static void
90 dummy_cb_fn(void *cb_arg, int status)
91 {
92 	CU_ASSERT(*(uint32_t *)cb_arg == DUMMY_ARG);
93 	CU_ASSERT(status == 0);
94 	g_dummy_cb_called = true;
95 }
96 
97 static void
98 test_spdk_accel_task_complete(void)
99 {
100 	struct spdk_accel_task accel_task = {};
101 	struct spdk_accel_task *expected_accel_task = NULL;
102 	uint32_t cb_arg = DUMMY_ARG;
103 	int status = 0;
104 
105 	accel_task.accel_ch = g_accel_ch;
106 	accel_task.cb_fn = dummy_cb_fn;
107 	accel_task.cb_arg = &cb_arg;
108 	TAILQ_INIT(&g_accel_ch->task_pool);
109 
110 	/* Confirm cb is called and task added to list. */
111 	spdk_accel_task_complete(&accel_task, status);
112 	CU_ASSERT(g_dummy_cb_called == true);
113 	expected_accel_task = TAILQ_FIRST(&g_accel_ch->task_pool);
114 	TAILQ_REMOVE(&g_accel_ch->task_pool, expected_accel_task, link);
115 	CU_ASSERT(expected_accel_task == &accel_task);
116 }
117 
118 static void
119 test_get_task(void)
120 {
121 	struct spdk_accel_task *task;
122 	struct spdk_accel_task _task;
123 	void *cb_arg = NULL;
124 
125 	TAILQ_INIT(&g_accel_ch->task_pool);
126 
127 	/* no tasks left, return NULL. */
128 	task = _get_task(g_accel_ch, dummy_cb_fn, cb_arg);
129 	CU_ASSERT(task == NULL);
130 
131 	_task.cb_fn = dummy_cb_fn;
132 	_task.cb_arg = cb_arg;
133 	_task.accel_ch = g_accel_ch;
134 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &_task, link);
135 
136 	/* Get a valid task. */
137 	task = _get_task(g_accel_ch, dummy_cb_fn, cb_arg);
138 	CU_ASSERT(task == &_task);
139 	CU_ASSERT(_task.cb_fn == dummy_cb_fn);
140 	CU_ASSERT(_task.cb_arg == cb_arg);
141 	CU_ASSERT(_task.accel_ch == g_accel_ch);
142 }
143 
144 #define TEST_SUBMIT_SIZE 64
145 static void
146 test_spdk_accel_submit_copy(void)
147 {
148 	const uint64_t nbytes = TEST_SUBMIT_SIZE;
149 	uint8_t dst[TEST_SUBMIT_SIZE] = {0};
150 	uint8_t src[TEST_SUBMIT_SIZE] = {0};
151 	void *cb_arg = NULL;
152 	int rc;
153 	struct spdk_accel_task task;
154 	struct spdk_accel_task *expected_accel_task = NULL;
155 	int flags = 0;
156 
157 	TAILQ_INIT(&g_accel_ch->task_pool);
158 
159 	/* Fail with no tasks on _get_task() */
160 	rc = spdk_accel_submit_copy(g_ch, src, dst, nbytes, flags, NULL, cb_arg);
161 	CU_ASSERT(rc == -ENOMEM);
162 
163 	task.accel_ch = g_accel_ch;
164 	task.flags = 1;
165 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
166 
167 	/* submission OK. */
168 	rc = spdk_accel_submit_copy(g_ch, dst, src, nbytes, flags, NULL, cb_arg);
169 	CU_ASSERT(rc == 0);
170 	CU_ASSERT(task.dst == dst);
171 	CU_ASSERT(task.src == src);
172 	CU_ASSERT(task.op_code == ACCEL_OPC_COPY);
173 	CU_ASSERT(task.nbytes == nbytes);
174 	CU_ASSERT(task.flags == 0);
175 	CU_ASSERT(memcmp(dst, src, TEST_SUBMIT_SIZE) == 0);
176 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
177 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
178 	CU_ASSERT(expected_accel_task == &task);
179 }
180 
181 static void
182 test_spdk_accel_submit_dualcast(void)
183 {
184 	void *dst1;
185 	void *dst2;
186 	void *src;
187 	uint32_t align = ALIGN_4K;
188 	uint64_t nbytes = TEST_SUBMIT_SIZE;
189 	void *cb_arg = NULL;
190 	int rc;
191 	struct spdk_accel_task task;
192 	struct spdk_accel_task *expected_accel_task = NULL;
193 	int flags = 0;
194 
195 	TAILQ_INIT(&g_accel_ch->task_pool);
196 
197 	/* Dualcast requires 4K alignment on dst addresses,
198 	 * hence using the hard coded address to test the buffer alignment
199 	 */
200 	dst1 = (void *)0x5000;
201 	dst2 = (void *)0x60f0;
202 	src = calloc(1, TEST_SUBMIT_SIZE);
203 	SPDK_CU_ASSERT_FATAL(src != NULL);
204 	memset(src, 0x5A, TEST_SUBMIT_SIZE);
205 
206 	/* This should fail since dst2 is not 4k aligned */
207 	rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, flags, NULL, cb_arg);
208 	CU_ASSERT(rc == -EINVAL);
209 
210 	dst1 = (void *)0x7010;
211 	dst2 = (void *)0x6000;
212 	/* This should fail since dst1 is not 4k aligned */
213 	rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, flags, NULL, cb_arg);
214 	CU_ASSERT(rc == -EINVAL);
215 
216 	/* Dualcast requires 4K alignment on dst addresses */
217 	dst1 = (void *)0x7000;
218 	dst2 = (void *)0x6000;
219 	/* Fail with no tasks on _get_task() */
220 	rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, flags, NULL, cb_arg);
221 	CU_ASSERT(rc == -ENOMEM);
222 
223 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
224 
225 	/* accel submission OK., since we test the SW path , need to use valid memory addresses
226 	 * cannot hardcode them anymore */
227 	dst1 = spdk_dma_zmalloc(nbytes, align, NULL);
228 	SPDK_CU_ASSERT_FATAL(dst1 != NULL);
229 	dst2 = spdk_dma_zmalloc(nbytes, align, NULL);
230 	SPDK_CU_ASSERT_FATAL(dst2 != NULL);
231 	/* SW module does the dualcast. */
232 	rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, flags, NULL, cb_arg);
233 	CU_ASSERT(rc == 0);
234 	CU_ASSERT(task.dst == dst1);
235 	CU_ASSERT(task.dst2 == dst2);
236 	CU_ASSERT(task.src == src);
237 	CU_ASSERT(task.op_code == ACCEL_OPC_DUALCAST);
238 	CU_ASSERT(task.nbytes == nbytes);
239 	CU_ASSERT(task.flags == 0);
240 	CU_ASSERT(memcmp(dst1, src, TEST_SUBMIT_SIZE) == 0);
241 	CU_ASSERT(memcmp(dst2, src, TEST_SUBMIT_SIZE) == 0);
242 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
243 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
244 	CU_ASSERT(expected_accel_task == &task);
245 
246 	free(src);
247 	spdk_free(dst1);
248 	spdk_free(dst2);
249 }
250 
251 static void
252 test_spdk_accel_submit_compare(void)
253 {
254 	void *src1;
255 	void *src2;
256 	uint64_t nbytes = TEST_SUBMIT_SIZE;
257 	void *cb_arg = NULL;
258 	int rc;
259 	struct spdk_accel_task task;
260 	struct spdk_accel_task *expected_accel_task = NULL;
261 
262 	TAILQ_INIT(&g_accel_ch->task_pool);
263 
264 	src1 = calloc(1, TEST_SUBMIT_SIZE);
265 	SPDK_CU_ASSERT_FATAL(src1 != NULL);
266 	src2 = calloc(1, TEST_SUBMIT_SIZE);
267 	SPDK_CU_ASSERT_FATAL(src2 != NULL);
268 
269 	/* Fail with no tasks on _get_task() */
270 	rc = spdk_accel_submit_compare(g_ch, src1, src2, nbytes, NULL, cb_arg);
271 	CU_ASSERT(rc == -ENOMEM);
272 
273 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
274 
275 	/* accel submission OK. */
276 	rc = spdk_accel_submit_compare(g_ch, src1, src2, nbytes, NULL, cb_arg);
277 	CU_ASSERT(rc == 0);
278 	CU_ASSERT(task.src == src1);
279 	CU_ASSERT(task.src2 == src2);
280 	CU_ASSERT(task.op_code == ACCEL_OPC_COMPARE);
281 	CU_ASSERT(task.nbytes == nbytes);
282 	CU_ASSERT(memcmp(src1, src2, TEST_SUBMIT_SIZE) == 0);
283 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
284 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
285 	CU_ASSERT(expected_accel_task == &task);
286 
287 	free(src1);
288 	free(src2);
289 }
290 
291 static void
292 test_spdk_accel_submit_fill(void)
293 {
294 	void *dst;
295 	void *src;
296 	uint8_t fill = 0xf;
297 	uint64_t fill64;
298 	uint64_t nbytes = TEST_SUBMIT_SIZE;
299 	void *cb_arg = NULL;
300 	int rc;
301 	struct spdk_accel_task task;
302 	struct spdk_accel_task *expected_accel_task = NULL;
303 	int flags = 0;
304 
305 	TAILQ_INIT(&g_accel_ch->task_pool);
306 
307 	dst = calloc(1, TEST_SUBMIT_SIZE);
308 	SPDK_CU_ASSERT_FATAL(dst != NULL);
309 	src = calloc(1, TEST_SUBMIT_SIZE);
310 	SPDK_CU_ASSERT_FATAL(src != NULL);
311 	memset(src, fill, TEST_SUBMIT_SIZE);
312 	memset(&fill64, fill, sizeof(uint64_t));
313 
314 	/* Fail with no tasks on _get_task() */
315 	rc = spdk_accel_submit_fill(g_ch, dst, fill, nbytes, flags, NULL, cb_arg);
316 	CU_ASSERT(rc == -ENOMEM);
317 
318 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
319 
320 	/* accel submission OK. */
321 	rc = spdk_accel_submit_fill(g_ch, dst, fill, nbytes, flags, NULL, cb_arg);
322 	CU_ASSERT(rc == 0);
323 	CU_ASSERT(task.dst == dst);
324 	CU_ASSERT(task.fill_pattern == fill64);
325 	CU_ASSERT(task.op_code == ACCEL_OPC_FILL);
326 	CU_ASSERT(task.nbytes == nbytes);
327 	CU_ASSERT(task.flags == 0);
328 
329 	CU_ASSERT(memcmp(dst, src, TEST_SUBMIT_SIZE) == 0);
330 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
331 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
332 	CU_ASSERT(expected_accel_task == &task);
333 
334 	free(dst);
335 	free(src);
336 }
337 
338 static void
339 test_spdk_accel_submit_crc32c(void)
340 {
341 	const uint64_t nbytes = TEST_SUBMIT_SIZE;
342 	uint32_t crc_dst;
343 	uint8_t src[TEST_SUBMIT_SIZE];
344 	uint32_t seed = 1;
345 	void *cb_arg = NULL;
346 	int rc;
347 	struct spdk_accel_task task;
348 	struct spdk_accel_task *expected_accel_task = NULL;
349 
350 	TAILQ_INIT(&g_accel_ch->task_pool);
351 
352 	/* Fail with no tasks on _get_task() */
353 	rc = spdk_accel_submit_crc32c(g_ch, &crc_dst, src, seed, nbytes, NULL, cb_arg);
354 	CU_ASSERT(rc == -ENOMEM);
355 
356 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
357 
358 	/* accel submission OK. */
359 	rc = spdk_accel_submit_crc32c(g_ch, &crc_dst, src, seed, nbytes, NULL, cb_arg);
360 	CU_ASSERT(rc == 0);
361 	CU_ASSERT(task.crc_dst == &crc_dst);
362 	CU_ASSERT(task.src == src);
363 	CU_ASSERT(task.s.iovcnt == 0);
364 	CU_ASSERT(task.seed == seed);
365 	CU_ASSERT(task.op_code == ACCEL_OPC_CRC32C);
366 	CU_ASSERT(task.nbytes == nbytes);
367 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
368 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
369 	CU_ASSERT(expected_accel_task == &task);
370 }
371 
372 static void
373 test_spdk_accel_submit_crc32cv(void)
374 {
375 	uint32_t crc_dst;
376 	uint32_t seed = 0;
377 	uint32_t iov_cnt = 32;
378 	void *cb_arg = NULL;
379 	int rc;
380 	uint32_t i = 0;
381 	struct spdk_accel_task task;
382 	struct iovec iov[32];
383 	struct spdk_accel_task *expected_accel_task = NULL;
384 
385 	TAILQ_INIT(&g_accel_ch->task_pool);
386 
387 	for (i = 0; i < iov_cnt; i++) {
388 		iov[i].iov_base = calloc(1, TEST_SUBMIT_SIZE);
389 		SPDK_CU_ASSERT_FATAL(iov[i].iov_base != NULL);
390 		iov[i].iov_len = TEST_SUBMIT_SIZE;
391 	}
392 
393 	task.nbytes = TEST_SUBMIT_SIZE;
394 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
395 
396 	/* accel submission OK. */
397 	rc = spdk_accel_submit_crc32cv(g_ch, &crc_dst, iov, iov_cnt, seed, NULL, cb_arg);
398 	CU_ASSERT(rc == 0);
399 	CU_ASSERT(task.s.iovs == iov);
400 	CU_ASSERT(task.s.iovcnt == iov_cnt);
401 	CU_ASSERT(task.crc_dst == &crc_dst);
402 	CU_ASSERT(task.seed == seed);
403 	CU_ASSERT(task.op_code == ACCEL_OPC_CRC32C);
404 	CU_ASSERT(task.cb_arg == cb_arg);
405 	CU_ASSERT(task.nbytes == iov[0].iov_len);
406 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
407 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
408 	CU_ASSERT(expected_accel_task == &task);
409 
410 	for (i = 0; i < iov_cnt; i++) {
411 		free(iov[i].iov_base);
412 	}
413 }
414 
415 static void
416 test_spdk_accel_submit_copy_crc32c(void)
417 {
418 	const uint64_t nbytes = TEST_SUBMIT_SIZE;
419 	uint32_t crc_dst;
420 	uint8_t dst[TEST_SUBMIT_SIZE];
421 	uint8_t src[TEST_SUBMIT_SIZE];
422 	uint32_t seed = 0;
423 	void *cb_arg = NULL;
424 	int rc;
425 	struct spdk_accel_task task;
426 	struct spdk_accel_task *expected_accel_task = NULL;
427 	int flags = 0;
428 
429 	TAILQ_INIT(&g_accel_ch->task_pool);
430 
431 	/* Fail with no tasks on _get_task() */
432 	rc = spdk_accel_submit_copy_crc32c(g_ch, dst, src, &crc_dst, seed, nbytes, flags,
433 					   NULL, cb_arg);
434 	CU_ASSERT(rc == -ENOMEM);
435 
436 	TAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
437 
438 	/* accel submission OK. */
439 	rc = spdk_accel_submit_copy_crc32c(g_ch, dst, src, &crc_dst, seed, nbytes, flags,
440 					   NULL, cb_arg);
441 	CU_ASSERT(rc == 0);
442 	CU_ASSERT(task.dst == dst);
443 	CU_ASSERT(task.src == src);
444 	CU_ASSERT(task.crc_dst == &crc_dst);
445 	CU_ASSERT(task.s.iovcnt == 0);
446 	CU_ASSERT(task.seed == seed);
447 	CU_ASSERT(task.nbytes == nbytes);
448 	CU_ASSERT(task.flags == 0);
449 	CU_ASSERT(task.op_code == ACCEL_OPC_COPY_CRC32C);
450 	expected_accel_task = TAILQ_FIRST(&g_sw_ch->tasks_to_complete);
451 	TAILQ_REMOVE(&g_sw_ch->tasks_to_complete, expected_accel_task, link);
452 	CU_ASSERT(expected_accel_task == &task);
453 }
454 
455 static void
456 test_spdk_accel_module_find_by_name(void)
457 {
458 	struct spdk_accel_module_if mod1 = {};
459 	struct spdk_accel_module_if mod2 = {};
460 	struct spdk_accel_module_if mod3 = {};
461 	struct spdk_accel_module_if *accel_module = NULL;
462 
463 	mod1.name = "ioat";
464 	mod2.name = "idxd";
465 	mod3.name = "software";
466 
467 	TAILQ_INIT(&spdk_accel_module_list);
468 	TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod1, tailq);
469 	TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod2, tailq);
470 	TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod3, tailq);
471 
472 	/* Now let's find a valid engine */
473 	accel_module = _module_find_by_name("ioat");
474 	CU_ASSERT(accel_module != NULL);
475 
476 	/* Try to find one that doesn't exist */
477 	accel_module = _module_find_by_name("XXX");
478 	CU_ASSERT(accel_module == NULL);
479 }
480 
481 static void
482 test_spdk_accel_module_register(void)
483 {
484 	struct spdk_accel_module_if mod1 = {};
485 	struct spdk_accel_module_if mod2 = {};
486 	struct spdk_accel_module_if mod3 = {};
487 	struct spdk_accel_module_if mod4 = {};
488 	struct spdk_accel_module_if *accel_module = NULL;
489 	int i = 0;
490 
491 	mod1.name = "ioat";
492 	mod2.name = "idxd";
493 	mod3.name = "software";
494 	mod4.name = "nothing";
495 
496 	TAILQ_INIT(&spdk_accel_module_list);
497 
498 	spdk_accel_module_list_add(&mod1);
499 	spdk_accel_module_list_add(&mod2);
500 	spdk_accel_module_list_add(&mod3);
501 	spdk_accel_module_list_add(&mod4);
502 
503 	/* Now confirm they're in the right order. */
504 	TAILQ_FOREACH(accel_module, &spdk_accel_module_list, tailq) {
505 		switch (i++) {
506 		case 0:
507 			CU_ASSERT(strcmp(accel_module->name, "software") == 0);
508 			break;
509 		case 1:
510 			CU_ASSERT(strcmp(accel_module->name, "ioat") == 0);
511 			break;
512 		case 2:
513 			CU_ASSERT(strcmp(accel_module->name, "idxd") == 0);
514 			break;
515 		case 3:
516 			CU_ASSERT(strcmp(accel_module->name, "nothing") == 0);
517 			break;
518 		default:
519 			CU_ASSERT(false);
520 			break;
521 		}
522 	}
523 	CU_ASSERT(i == 4);
524 }
525 
526 int
527 main(int argc, char **argv)
528 {
529 	CU_pSuite	suite = NULL;
530 	unsigned int	num_failures;
531 
532 	CU_set_error_action(CUEA_ABORT);
533 	CU_initialize_registry();
534 
535 	suite = CU_add_suite("accel", test_setup, test_cleanup);
536 
537 	CU_ADD_TEST(suite, test_spdk_accel_task_complete);
538 	CU_ADD_TEST(suite, test_get_task);
539 	CU_ADD_TEST(suite, test_spdk_accel_submit_copy);
540 	CU_ADD_TEST(suite, test_spdk_accel_submit_dualcast);
541 	CU_ADD_TEST(suite, test_spdk_accel_submit_compare);
542 	CU_ADD_TEST(suite, test_spdk_accel_submit_fill);
543 	CU_ADD_TEST(suite, test_spdk_accel_submit_crc32c);
544 	CU_ADD_TEST(suite, test_spdk_accel_submit_crc32cv);
545 	CU_ADD_TEST(suite, test_spdk_accel_submit_copy_crc32c);
546 	CU_ADD_TEST(suite, test_spdk_accel_module_find_by_name);
547 	CU_ADD_TEST(suite, test_spdk_accel_module_register);
548 
549 	CU_basic_set_mode(CU_BRM_VERBOSE);
550 	CU_basic_run_tests();
551 	num_failures = CU_get_number_of_failures();
552 	CU_cleanup_registry();
553 
554 	return num_failures;
555 }
556