Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2022, 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk_internal/cunit.h"
8 : : #include "spdk_internal/mock.h"
9 : : #include "spdk/accel_module.h"
10 : : #include "thread/thread_internal.h"
11 : : #include "common/lib/ut_multithread.c"
12 : : #include "common/lib/test_iobuf.c"
13 : : #include "accel/accel.c"
14 : : #include "accel/accel_sw.c"
15 : : #include "unit/lib/json_mock.c"
16 : :
17 : 6 : DEFINE_STUB_V(spdk_memory_domain_destroy, (struct spdk_memory_domain *domain));
18 [ - + - + ]: 6 : DEFINE_STUB(spdk_memory_domain_get_dma_device_id, const char *,
19 : : (struct spdk_memory_domain *domain), "UT_DMA");
20 [ # # # # ]: 0 : DEFINE_STUB(spdk_memory_domain_get_system_domain, struct spdk_memory_domain *, (void),
21 : : (void *)0xabc);
22 : 6 : DEFINE_STUB_V(spdk_memory_domain_set_invalidate, (struct spdk_memory_domain *domain,
23 : : spdk_memory_domain_invalidate_data_cb invalidate_cb));
24 : 6 : DEFINE_STUB_V(spdk_memory_domain_set_translation, (struct spdk_memory_domain *domain,
25 : : spdk_memory_domain_translate_memory_cb translate_cb));
26 : :
27 : : int
28 : 6 : spdk_memory_domain_create(struct spdk_memory_domain **domain, enum spdk_dma_device_type type,
29 : : struct spdk_memory_domain_ctx *ctx, const char *id)
30 : : {
31 : 6 : *domain = (void *)0xdeadbeef;
32 : :
33 : 6 : return 0;
34 : : }
35 : :
36 : : struct ut_domain_ctx {
37 : : struct iovec iov;
38 : : struct iovec expected;
39 : : int pull_submit_status;
40 : : int push_submit_status;
41 : : int pull_complete_status;
42 : : int push_complete_status;
43 : : };
44 : :
45 : : static struct spdk_memory_domain *g_ut_domain = (void *)0xa55e1;
46 : :
47 : : int
48 : 27 : spdk_memory_domain_pull_data(struct spdk_memory_domain *sd, void *sctx, struct iovec *siov,
49 : : uint32_t siovcnt, struct iovec *diov, uint32_t diovcnt,
50 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_arg)
51 : : {
52 : 27 : struct ut_domain_ctx *ctx = sctx;
53 : :
54 : 27 : CU_ASSERT_EQUAL(sd, g_ut_domain);
55 : 27 : CU_ASSERT_EQUAL(siovcnt, 1);
56 [ - + - + ]: 27 : CU_ASSERT_EQUAL(memcmp(siov, &ctx->expected, sizeof(*siov)), 0);
57 : :
58 [ + + ]: 27 : if (ctx->pull_submit_status != 0) {
59 : 3 : return ctx->pull_submit_status;
60 : : }
61 : :
62 [ + + ]: 24 : if (ctx->pull_complete_status != 0) {
63 : 3 : cpl_cb(cpl_arg, ctx->pull_complete_status);
64 : 3 : return 0;
65 : : }
66 : :
67 : 21 : spdk_iovcpy(&ctx->iov, 1, diov, diovcnt);
68 : 21 : cpl_cb(cpl_arg, 0);
69 : :
70 : 21 : return 0;
71 : 9 : }
72 : :
73 : : int
74 : 24 : spdk_memory_domain_push_data(struct spdk_memory_domain *dd, void *dctx, struct iovec *diov,
75 : : uint32_t diovcnt, struct iovec *siov, uint32_t siovcnt,
76 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_arg)
77 : : {
78 : 24 : struct ut_domain_ctx *ctx = dctx;
79 : :
80 : 24 : CU_ASSERT_EQUAL(dd, g_ut_domain);
81 : 24 : CU_ASSERT_EQUAL(diovcnt, 1);
82 [ - + - + ]: 24 : CU_ASSERT_EQUAL(memcmp(diov, &ctx->expected, sizeof(*diov)), 0);
83 : :
84 [ + + ]: 24 : if (ctx->push_submit_status != 0) {
85 : 3 : return ctx->push_submit_status;
86 : : }
87 : :
88 [ + + ]: 21 : if (ctx->push_complete_status != 0) {
89 : 3 : cpl_cb(cpl_arg, ctx->push_complete_status);
90 : 3 : return 0;
91 : : }
92 : :
93 : 18 : spdk_iovcpy(siov, siovcnt, &ctx->iov, 1);
94 : 18 : cpl_cb(cpl_arg, 0);
95 : :
96 : 18 : return 0;
97 : 8 : }
98 : :
99 : : /* global vars and setup/cleanup functions used for all test functions */
100 : : struct spdk_accel_module_if g_module_if = {};
101 : : struct accel_module g_module = { .module = &g_module_if };
102 : : struct spdk_io_channel *g_ch = NULL;
103 : : struct accel_io_channel *g_accel_ch = NULL;
104 : : struct sw_accel_io_channel *g_sw_ch = NULL;
105 : : struct spdk_io_channel *g_module_ch = NULL;
106 : :
107 : : static uint64_t g_opc_mask = 0;
108 : :
109 : : static uint64_t
110 : 0 : _accel_op_to_bit(enum spdk_accel_opcode opc)
111 : : {
112 [ # # ]: 0 : return (1 << opc);
113 : : }
114 : :
115 : : static bool
116 : 0 : _supports_opcode(enum spdk_accel_opcode opc)
117 : : {
118 [ # # ]: 0 : if (_accel_op_to_bit(opc) & g_opc_mask) {
119 : 0 : return true;
120 : : }
121 : 0 : return false;
122 : 0 : }
123 : :
124 : : static bool
125 : 114 : _supports_algo(enum spdk_accel_comp_algo algo)
126 : : {
127 : 114 : return true;
128 : : }
129 : :
130 : : static int
131 : 0 : _get_compress_level_range(enum spdk_accel_comp_algo algo, uint32_t *min_level, uint32_t *max_level)
132 : : {
133 : 0 : *min_level = 0;
134 : 0 : *max_level = UINT32_MAX;
135 : :
136 : 0 : return 0;
137 : : }
138 : :
139 : : static int
140 : 3 : test_setup(void)
141 : : {
142 : : int i;
143 : :
144 : 3 : g_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct accel_io_channel));
145 [ + + ]: 3 : if (g_ch == NULL) {
146 : : /* for some reason the assert fatal macro doesn't work in the setup function. */
147 : 0 : CU_ASSERT(false);
148 : 0 : return -1;
149 : : }
150 : 3 : g_accel_ch = (struct accel_io_channel *)((char *)g_ch + sizeof(struct spdk_io_channel));
151 : 3 : g_module_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct sw_accel_io_channel));
152 [ - + ]: 3 : if (g_module_ch == NULL) {
153 : 0 : CU_ASSERT(false);
154 : 0 : return -1;
155 : : }
156 : :
157 : 3 : g_module_if.submit_tasks = sw_accel_submit_tasks;
158 : 3 : g_module_if.name = "software";
159 : 3 : g_module_if.compress_supports_algo = _supports_algo;
160 : 3 : g_module_if.get_compress_level_range = _get_compress_level_range;
161 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; i++) {
162 : 51 : g_accel_ch->module_ch[i] = g_module_ch;
163 : 51 : g_modules_opc[i] = g_module;
164 : 17 : }
165 : 3 : g_sw_ch = (struct sw_accel_io_channel *)((char *)g_module_ch + sizeof(
166 : : struct spdk_io_channel));
167 : : /* Prevent lazy initialization of poller. */
168 : 3 : g_sw_ch->completion_poller = (void *)0xdeadbeef;
169 : 3 : STAILQ_INIT(&g_sw_ch->tasks_to_complete);
170 : 3 : g_module_if.supports_opcode = _supports_opcode;
171 : 3 : return 0;
172 : 1 : }
173 : :
174 : : static int
175 : 3 : test_cleanup(void)
176 : : {
177 : 3 : free(g_ch);
178 : 3 : free(g_module_ch);
179 : :
180 : 3 : return 0;
181 : : }
182 : :
183 : : #define DUMMY_ARG 0xDEADBEEF
184 : : static bool g_dummy_cb_called = false;
185 : : static void
186 : 3 : dummy_cb_fn(void *cb_arg, int status)
187 : : {
188 : 3 : CU_ASSERT(*(uint32_t *)cb_arg == DUMMY_ARG);
189 : 3 : CU_ASSERT(status == 0);
190 : 3 : g_dummy_cb_called = true;
191 : 3 : }
192 : :
193 : : static void
194 : 3 : test_spdk_accel_task_complete(void)
195 : : {
196 : 3 : struct spdk_accel_task accel_task = {};
197 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
198 : 3 : uint32_t cb_arg = DUMMY_ARG;
199 : 3 : int status = 0;
200 : :
201 : 3 : accel_task.accel_ch = g_accel_ch;
202 : 3 : accel_task.cb_fn = dummy_cb_fn;
203 : 3 : accel_task.cb_arg = &cb_arg;
204 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
205 : :
206 : : /* Confirm cb is called and task added to list. */
207 : 3 : spdk_accel_task_complete(&accel_task, status);
208 [ - + ]: 3 : CU_ASSERT(g_dummy_cb_called == true);
209 : 3 : expected_accel_task = STAILQ_FIRST(&g_accel_ch->task_pool);
210 [ + - ]: 3 : STAILQ_REMOVE_HEAD(&g_accel_ch->task_pool, link);
211 : 3 : CU_ASSERT(expected_accel_task == &accel_task);
212 : 3 : }
213 : :
214 : : static void
215 : 3 : test_get_task(void)
216 : : {
217 : : struct spdk_accel_task *task;
218 : 2 : struct spdk_accel_task _task;
219 : 3 : void *cb_arg = NULL;
220 : :
221 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
222 : :
223 : : /* no tasks left, return NULL. */
224 : 3 : task = _get_task(g_accel_ch, dummy_cb_fn, cb_arg);
225 : 3 : CU_ASSERT(task == NULL);
226 : :
227 : 3 : _task.cb_fn = dummy_cb_fn;
228 : 3 : _task.cb_arg = cb_arg;
229 : 3 : _task.accel_ch = g_accel_ch;
230 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &_task, link);
231 : :
232 : : /* Get a valid task. */
233 : 3 : task = _get_task(g_accel_ch, dummy_cb_fn, cb_arg);
234 : 3 : CU_ASSERT(task == &_task);
235 : 3 : CU_ASSERT(_task.cb_fn == dummy_cb_fn);
236 : 3 : CU_ASSERT(_task.cb_arg == cb_arg);
237 : 3 : CU_ASSERT(_task.accel_ch == g_accel_ch);
238 : 3 : }
239 : :
240 : : #define TEST_SUBMIT_SIZE 64
241 : : static void
242 : 3 : test_spdk_accel_submit_copy(void)
243 : : {
244 : 3 : const uint64_t nbytes = TEST_SUBMIT_SIZE;
245 : 3 : uint8_t dst[TEST_SUBMIT_SIZE] = {0};
246 : 3 : uint8_t src[TEST_SUBMIT_SIZE] = {0};
247 : 3 : void *cb_arg = NULL;
248 : : int rc;
249 : 2 : struct spdk_accel_task task;
250 : 2 : struct spdk_accel_task_aux_data task_aux;
251 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
252 : :
253 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
254 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
255 : :
256 : : /* Fail with no tasks on _get_task() */
257 : 3 : rc = spdk_accel_submit_copy(g_ch, src, dst, nbytes, NULL, cb_arg);
258 : 3 : CU_ASSERT(rc == -ENOMEM);
259 : :
260 : 3 : task.accel_ch = g_accel_ch;
261 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
262 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
263 : :
264 : : /* submission OK. */
265 : 3 : rc = spdk_accel_submit_copy(g_ch, dst, src, nbytes, NULL, cb_arg);
266 : 3 : CU_ASSERT(rc == 0);
267 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_COPY);
268 : 3 : CU_ASSERT(memcmp(dst, src, TEST_SUBMIT_SIZE) == 0);
269 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
270 [ + - ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
271 : 3 : CU_ASSERT(expected_accel_task == &task);
272 : 3 : }
273 : :
274 : : static void
275 : 3 : test_spdk_accel_submit_dualcast(void)
276 : : {
277 : : void *dst1;
278 : : void *dst2;
279 : : void *src;
280 : 3 : uint32_t align = ALIGN_4K;
281 : 3 : uint64_t nbytes = TEST_SUBMIT_SIZE;
282 : 3 : void *cb_arg = NULL;
283 : : int rc;
284 : 2 : struct spdk_accel_task task;
285 : 2 : struct spdk_accel_task_aux_data task_aux;
286 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
287 : :
288 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
289 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
290 : :
291 : : /* Dualcast requires 4K alignment on dst addresses,
292 : : * hence using the hard coded address to test the buffer alignment
293 : : */
294 : 3 : dst1 = (void *)0x5000;
295 : 3 : dst2 = (void *)0x60f0;
296 : 3 : src = calloc(1, TEST_SUBMIT_SIZE);
297 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(src != NULL);
298 [ - + ]: 3 : memset(src, 0x5A, TEST_SUBMIT_SIZE);
299 : :
300 : : /* This should fail since dst2 is not 4k aligned */
301 : 3 : rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, NULL, cb_arg);
302 : 3 : CU_ASSERT(rc == -EINVAL);
303 : :
304 : 3 : dst1 = (void *)0x7010;
305 : 3 : dst2 = (void *)0x6000;
306 : : /* This should fail since dst1 is not 4k aligned */
307 : 3 : rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, NULL, cb_arg);
308 : 3 : CU_ASSERT(rc == -EINVAL);
309 : :
310 : : /* Dualcast requires 4K alignment on dst addresses */
311 : 3 : dst1 = (void *)0x7000;
312 : 3 : dst2 = (void *)0x6000;
313 : : /* Fail with no tasks on _get_task() */
314 : 3 : rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, NULL, cb_arg);
315 : 3 : CU_ASSERT(rc == -ENOMEM);
316 : :
317 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
318 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
319 : :
320 : : /* accel submission OK., since we test the SW path , need to use valid memory addresses
321 : : * cannot hardcode them anymore */
322 : 3 : dst1 = spdk_dma_zmalloc(nbytes, align, NULL);
323 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(dst1 != NULL);
324 : 3 : dst2 = spdk_dma_zmalloc(nbytes, align, NULL);
325 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(dst2 != NULL);
326 : : /* SW module does the dualcast. */
327 : 3 : rc = spdk_accel_submit_dualcast(g_ch, dst1, dst2, src, nbytes, NULL, cb_arg);
328 : 3 : CU_ASSERT(rc == 0);
329 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_DUALCAST);
330 [ - + - + ]: 3 : CU_ASSERT(memcmp(dst1, src, TEST_SUBMIT_SIZE) == 0);
331 [ - + - + ]: 3 : CU_ASSERT(memcmp(dst2, src, TEST_SUBMIT_SIZE) == 0);
332 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
333 [ + + ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
334 : 3 : CU_ASSERT(expected_accel_task == &task);
335 : :
336 : 3 : free(src);
337 : 3 : spdk_free(dst1);
338 : 3 : spdk_free(dst2);
339 : 3 : }
340 : :
341 : : static void
342 : 3 : test_spdk_accel_submit_compare(void)
343 : : {
344 : : void *src1;
345 : : void *src2;
346 : 3 : uint64_t nbytes = TEST_SUBMIT_SIZE;
347 : 3 : void *cb_arg = NULL;
348 : : int rc;
349 : 2 : struct spdk_accel_task task;
350 : 2 : struct spdk_accel_task_aux_data task_aux;
351 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
352 : :
353 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
354 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
355 : :
356 : 3 : src1 = calloc(1, TEST_SUBMIT_SIZE);
357 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(src1 != NULL);
358 : 3 : src2 = calloc(1, TEST_SUBMIT_SIZE);
359 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(src2 != NULL);
360 : :
361 : : /* Fail with no tasks on _get_task() */
362 : 3 : rc = spdk_accel_submit_compare(g_ch, src1, src2, nbytes, NULL, cb_arg);
363 : 3 : CU_ASSERT(rc == -ENOMEM);
364 : :
365 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
366 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
367 : :
368 : : /* accel submission OK. */
369 : 3 : rc = spdk_accel_submit_compare(g_ch, src1, src2, nbytes, NULL, cb_arg);
370 : 3 : CU_ASSERT(rc == 0);
371 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_COMPARE);
372 [ - + - + ]: 3 : CU_ASSERT(memcmp(src1, src2, TEST_SUBMIT_SIZE) == 0);
373 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
374 [ + + ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
375 : 3 : CU_ASSERT(expected_accel_task == &task);
376 : :
377 : 3 : free(src1);
378 : 3 : free(src2);
379 : 3 : }
380 : :
381 : : static void
382 : 3 : test_spdk_accel_submit_fill(void)
383 : : {
384 : : void *dst;
385 : : void *src;
386 : 3 : uint8_t fill = 0xf;
387 : 2 : uint64_t fill64;
388 : 3 : uint64_t nbytes = TEST_SUBMIT_SIZE;
389 : 3 : void *cb_arg = NULL;
390 : : int rc;
391 : 2 : struct spdk_accel_task task;
392 : 2 : struct spdk_accel_task_aux_data task_aux;
393 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
394 : :
395 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
396 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
397 : :
398 : 3 : dst = calloc(1, TEST_SUBMIT_SIZE);
399 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(dst != NULL);
400 : 3 : src = calloc(1, TEST_SUBMIT_SIZE);
401 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(src != NULL);
402 [ - + ]: 3 : memset(src, fill, TEST_SUBMIT_SIZE);
403 : 3 : memset(&fill64, fill, sizeof(uint64_t));
404 : :
405 : : /* Fail with no tasks on _get_task() */
406 : 3 : rc = spdk_accel_submit_fill(g_ch, dst, fill, nbytes, NULL, cb_arg);
407 : 3 : CU_ASSERT(rc == -ENOMEM);
408 : :
409 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
410 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
411 : :
412 : : /* accel submission OK. */
413 : 3 : rc = spdk_accel_submit_fill(g_ch, dst, fill, nbytes, NULL, cb_arg);
414 : 3 : CU_ASSERT(rc == 0);
415 : 3 : CU_ASSERT(task.fill_pattern == fill64);
416 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_FILL);
417 : :
418 [ - + - + ]: 3 : CU_ASSERT(memcmp(dst, src, TEST_SUBMIT_SIZE) == 0);
419 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
420 [ + + ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
421 : 3 : CU_ASSERT(expected_accel_task == &task);
422 : :
423 : 3 : free(dst);
424 : 3 : free(src);
425 : 3 : }
426 : :
427 : : static void
428 : 3 : test_spdk_accel_submit_crc32c(void)
429 : : {
430 : 3 : const uint64_t nbytes = TEST_SUBMIT_SIZE;
431 : 2 : uint32_t crc_dst;
432 : 2 : uint8_t src[TEST_SUBMIT_SIZE];
433 : 3 : uint32_t seed = 1;
434 : 3 : void *cb_arg = NULL;
435 : : int rc;
436 : 2 : struct spdk_accel_task task;
437 : 2 : struct spdk_accel_task_aux_data task_aux;
438 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
439 : :
440 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
441 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
442 : :
443 : : /* Fail with no tasks on _get_task() */
444 : 3 : rc = spdk_accel_submit_crc32c(g_ch, &crc_dst, src, seed, nbytes, NULL, cb_arg);
445 : 3 : CU_ASSERT(rc == -ENOMEM);
446 : :
447 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
448 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
449 : :
450 : : /* accel submission OK. */
451 : 3 : rc = spdk_accel_submit_crc32c(g_ch, &crc_dst, src, seed, nbytes, NULL, cb_arg);
452 : 3 : CU_ASSERT(rc == 0);
453 : 3 : CU_ASSERT(task.crc_dst == &crc_dst);
454 : 3 : CU_ASSERT(task.seed == seed);
455 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_CRC32C);
456 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
457 [ + - ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
458 : 3 : CU_ASSERT(expected_accel_task == &task);
459 : 3 : }
460 : :
461 : : static void
462 : 3 : test_spdk_accel_submit_crc32cv(void)
463 : : {
464 : 2 : uint32_t crc_dst;
465 : 3 : uint32_t seed = 0;
466 : 3 : uint32_t iov_cnt = 32;
467 : 3 : void *cb_arg = NULL;
468 : : int rc;
469 : 3 : uint32_t i = 0;
470 : 2 : struct spdk_accel_task task;
471 : 2 : struct spdk_accel_task_aux_data task_aux;
472 : 2 : struct iovec iov[32];
473 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
474 : :
475 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
476 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
477 : :
478 [ + + ]: 99 : for (i = 0; i < iov_cnt; i++) {
479 : 96 : iov[i].iov_base = calloc(1, TEST_SUBMIT_SIZE);
480 [ + + ]: 96 : SPDK_CU_ASSERT_FATAL(iov[i].iov_base != NULL);
481 : 96 : iov[i].iov_len = TEST_SUBMIT_SIZE;
482 : 32 : }
483 : :
484 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
485 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
486 : :
487 : : /* accel submission OK. */
488 : 3 : rc = spdk_accel_submit_crc32cv(g_ch, &crc_dst, iov, iov_cnt, seed, NULL, cb_arg);
489 : 3 : CU_ASSERT(rc == 0);
490 : 3 : CU_ASSERT(task.s.iovs == iov);
491 : 3 : CU_ASSERT(task.s.iovcnt == iov_cnt);
492 : 3 : CU_ASSERT(task.crc_dst == &crc_dst);
493 : 3 : CU_ASSERT(task.seed == seed);
494 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_CRC32C);
495 : 3 : CU_ASSERT(task.cb_arg == cb_arg);
496 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
497 [ + + ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
498 : 3 : CU_ASSERT(expected_accel_task == &task);
499 : :
500 [ + + ]: 99 : for (i = 0; i < iov_cnt; i++) {
501 : 96 : free(iov[i].iov_base);
502 : 32 : }
503 : 3 : }
504 : :
505 : : static void
506 : 3 : test_spdk_accel_submit_copy_crc32c(void)
507 : : {
508 : 3 : const uint64_t nbytes = TEST_SUBMIT_SIZE;
509 : 2 : uint32_t crc_dst;
510 : 2 : uint8_t dst[TEST_SUBMIT_SIZE];
511 : 2 : uint8_t src[TEST_SUBMIT_SIZE];
512 : 3 : uint32_t seed = 0;
513 : 3 : void *cb_arg = NULL;
514 : : int rc;
515 : 2 : struct spdk_accel_task task;
516 : 2 : struct spdk_accel_task_aux_data task_aux;
517 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
518 : :
519 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
520 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
521 : :
522 : : /* Fail with no tasks on _get_task() */
523 : 3 : rc = spdk_accel_submit_copy_crc32c(g_ch, dst, src, &crc_dst, seed, nbytes, NULL, cb_arg);
524 : 3 : CU_ASSERT(rc == -ENOMEM);
525 : :
526 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
527 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
528 : :
529 : : /* accel submission OK. */
530 : 3 : rc = spdk_accel_submit_copy_crc32c(g_ch, dst, src, &crc_dst, seed, nbytes, NULL, cb_arg);
531 : 3 : CU_ASSERT(rc == 0);
532 : 3 : CU_ASSERT(task.crc_dst == &crc_dst);
533 : 3 : CU_ASSERT(task.seed == seed);
534 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_COPY_CRC32C);
535 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
536 [ + - ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
537 : 3 : CU_ASSERT(expected_accel_task == &task);
538 : 3 : }
539 : :
540 : : static void
541 : 3 : test_spdk_accel_submit_xor(void)
542 : : {
543 : 3 : const uint64_t nbytes = TEST_SUBMIT_SIZE;
544 : 3 : uint8_t dst[TEST_SUBMIT_SIZE] = {0};
545 : 3 : uint8_t src1[TEST_SUBMIT_SIZE] = {0};
546 : 3 : uint8_t src2[TEST_SUBMIT_SIZE] = {0};
547 : 3 : void *sources[] = { src1, src2 };
548 : 3 : uint32_t nsrcs = SPDK_COUNTOF(sources);
549 : : int rc;
550 : 2 : struct spdk_accel_task task;
551 : 2 : struct spdk_accel_task_aux_data task_aux;
552 : 3 : struct spdk_accel_task *expected_accel_task = NULL;
553 : :
554 : 3 : STAILQ_INIT(&g_accel_ch->task_pool);
555 : 3 : SLIST_INIT(&g_accel_ch->task_aux_data_pool);
556 : :
557 : : /* Fail with no tasks on _get_task() */
558 : 3 : rc = spdk_accel_submit_xor(g_ch, dst, sources, nsrcs, nbytes, NULL, NULL);
559 : 3 : CU_ASSERT(rc == -ENOMEM);
560 : :
561 : 3 : STAILQ_INSERT_TAIL(&g_accel_ch->task_pool, &task, link);
562 : 3 : SLIST_INSERT_HEAD(&g_accel_ch->task_aux_data_pool, &task_aux, link);
563 : :
564 : : /* submission OK. */
565 : 3 : rc = spdk_accel_submit_xor(g_ch, dst, sources, nsrcs, nbytes, NULL, NULL);
566 : 3 : CU_ASSERT(rc == 0);
567 : 3 : CU_ASSERT(task.nsrcs.srcs == sources);
568 : 3 : CU_ASSERT(task.nsrcs.cnt == nsrcs);
569 : 3 : CU_ASSERT(task.d.iovcnt == 1);
570 : 3 : CU_ASSERT(task.d.iovs[0].iov_base == dst);
571 : 3 : CU_ASSERT(task.d.iovs[0].iov_len == nbytes);
572 : 3 : CU_ASSERT(task.op_code == SPDK_ACCEL_OPC_XOR);
573 : 3 : expected_accel_task = STAILQ_FIRST(&g_sw_ch->tasks_to_complete);
574 [ + - ]: 3 : STAILQ_REMOVE_HEAD(&g_sw_ch->tasks_to_complete, link);
575 : 3 : CU_ASSERT(expected_accel_task == &task);
576 : 3 : }
577 : :
578 : : static void
579 : 3 : test_spdk_accel_module_find_by_name(void)
580 : : {
581 : 3 : struct spdk_accel_module_if mod1 = {};
582 : 3 : struct spdk_accel_module_if mod2 = {};
583 : 3 : struct spdk_accel_module_if mod3 = {};
584 : 3 : struct spdk_accel_module_if *accel_module = NULL;
585 : :
586 : 3 : mod1.name = "ioat";
587 : 3 : mod2.name = "idxd";
588 : 3 : mod3.name = "software";
589 : :
590 : 3 : TAILQ_INIT(&spdk_accel_module_list);
591 : 3 : TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod1, tailq);
592 : 3 : TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod2, tailq);
593 : 3 : TAILQ_INSERT_TAIL(&spdk_accel_module_list, &mod3, tailq);
594 : :
595 : : /* Now let's find a valid engine */
596 : 3 : accel_module = _module_find_by_name("ioat");
597 : 3 : CU_ASSERT(accel_module != NULL);
598 : :
599 : : /* Try to find one that doesn't exist */
600 : 3 : accel_module = _module_find_by_name("XXX");
601 : 3 : CU_ASSERT(accel_module == NULL);
602 : 3 : }
603 : :
604 : : static int
605 : 12 : ut_module_init_nop(void)
606 : : {
607 : 12 : return 0;
608 : : }
609 : :
610 : : static bool
611 : 204 : ut_supports_opcode_all(enum spdk_accel_opcode opcode)
612 : : {
613 : 204 : return true;
614 : : }
615 : :
616 : : static void
617 : 3 : ut_accel_module_priority_finish_done(void *done)
618 : : {
619 : 3 : *(int *)done = 1;
620 : 3 : }
621 : :
622 : : static void
623 : 3 : test_spdk_accel_module_register(void)
624 : : {
625 : 3 : struct spdk_accel_module_if mods[] = {
626 : : { .name = "mod1", .priority = 1, },
627 : : { .name = "mod3", .priority = 3, },
628 : : { .name = "mod0", .priority = 0, },
629 : : { .name = "mod2", .priority = 2, },
630 : : };
631 : 3 : int rc, done = 0;
632 : 3 : const char *modname = NULL;
633 : : size_t i;
634 : :
635 : 3 : allocate_cores(1);
636 : 3 : allocate_threads(1);
637 : 3 : set_thread(0);
638 : :
639 : 3 : TAILQ_INIT(&spdk_accel_module_list);
640 [ + + ]: 15 : for (i = 0; i < SPDK_COUNTOF(mods); ++i) {
641 : 12 : mods[i].module_init = ut_module_init_nop;
642 : 12 : mods[i].supports_opcode = ut_supports_opcode_all;
643 : 12 : spdk_accel_module_list_add(&mods[i]);
644 : 4 : }
645 : :
646 : 3 : rc = spdk_accel_initialize();
647 : 3 : CU_ASSERT_EQUAL(rc, 0);
648 : :
649 : : /* All opcodes should be assigned to the module with highest prio - mod3 */
650 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
651 : 51 : rc = spdk_accel_get_opc_module_name((enum spdk_accel_opcode)i, &modname);
652 : 51 : CU_ASSERT_EQUAL(rc, 0);
653 [ - + ]: 51 : CU_ASSERT_STRING_EQUAL(modname, "mod3");
654 : 17 : }
655 : :
656 : 3 : spdk_accel_finish(ut_accel_module_priority_finish_done, &done);
657 [ + + ]: 6 : while (!done) {
658 : 3 : poll_threads();
659 : : }
660 : :
661 : 3 : TAILQ_INIT(&spdk_accel_module_list);
662 : 3 : free_threads();
663 : 3 : free_cores();
664 : 3 : }
665 : :
666 : : struct ut_sequence {
667 : : bool complete;
668 : : int status;
669 : : };
670 : :
671 : : static void
672 : 504 : ut_sequence_step_cb(void *cb_arg)
673 : : {
674 : 504 : int *completed = cb_arg;
675 : :
676 : 504 : (*completed)++;
677 : 504 : }
678 : :
679 : : static void
680 : 195 : ut_sequence_complete_cb(void *cb_arg, int status)
681 : : {
682 : 195 : struct ut_sequence *seq = cb_arg;
683 : :
684 : 195 : seq->complete = true;
685 : 195 : seq->status = status;
686 : 195 : }
687 : :
688 : : static void
689 : 3 : test_sequence_fill_copy(void)
690 : : {
691 : 3 : struct spdk_accel_sequence *seq = NULL;
692 : : struct spdk_io_channel *ioch;
693 : 2 : struct ut_sequence ut_seq;
694 : 2 : char buf[4096], tmp[2][4096], expected[4096];
695 : 2 : struct iovec src_iovs[2], dst_iovs[2];
696 : 2 : int rc, completed;
697 : :
698 : 3 : ioch = spdk_accel_get_io_channel();
699 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
700 : :
701 : : /* First check the simplest case - single task in a sequence */
702 : 3 : memset(buf, 0, sizeof(buf));
703 : 3 : memset(expected, 0xa5, sizeof(expected));
704 : 3 : completed = 0;
705 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, sizeof(buf), NULL, NULL, 0xa5,
706 : : ut_sequence_step_cb, &completed);
707 : 3 : CU_ASSERT_EQUAL(rc, 0);
708 : 3 : CU_ASSERT_EQUAL(completed, 0);
709 : :
710 : 3 : ut_seq.complete = false;
711 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
712 : :
713 : 3 : poll_threads();
714 : 3 : CU_ASSERT_EQUAL(completed, 1);
715 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
716 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
717 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
718 : :
719 : : /* Check a single copy operation */
720 : 3 : memset(buf, 0, sizeof(buf));
721 : 3 : memset(tmp[0], 0xa5, sizeof(tmp[0]));
722 : 3 : memset(expected, 0xa5, sizeof(expected));
723 : 3 : completed = 0;
724 : 3 : seq = NULL;
725 : :
726 : 3 : dst_iovs[0].iov_base = buf;
727 : 3 : dst_iovs[0].iov_len = sizeof(buf);
728 : 3 : src_iovs[0].iov_base = tmp[0];
729 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
730 : :
731 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
732 : 1 : &src_iovs[0], 1, NULL, NULL,
733 : : ut_sequence_step_cb, &completed);
734 : 3 : CU_ASSERT_EQUAL(rc, 0);
735 : :
736 : 3 : ut_seq.complete = false;
737 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
738 : :
739 : 3 : poll_threads();
740 : 3 : CU_ASSERT_EQUAL(completed, 1);
741 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
742 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
743 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
744 : :
745 : : /* Check multiple fill operations */
746 : 3 : memset(buf, 0, sizeof(buf));
747 : 3 : memset(expected, 0xfe, 4096);
748 : 3 : memset(expected, 0xde, 2048);
749 : 3 : memset(expected, 0xa5, 1024);
750 : 3 : seq = NULL;
751 : 3 : completed = 0;
752 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 4096, NULL, NULL, 0xfe,
753 : : ut_sequence_step_cb, &completed);
754 : 3 : CU_ASSERT_EQUAL(rc, 0);
755 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 2048, NULL, NULL, 0xde,
756 : : ut_sequence_step_cb, &completed);
757 : 3 : CU_ASSERT_EQUAL(rc, 0);
758 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 1024, NULL, NULL, 0xa5,
759 : : ut_sequence_step_cb, &completed);
760 : 3 : CU_ASSERT_EQUAL(rc, 0);
761 : :
762 : 3 : ut_seq.complete = false;
763 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
764 : :
765 : 3 : poll_threads();
766 : 3 : CU_ASSERT_EQUAL(completed, 3);
767 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
768 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
769 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
770 : :
771 : : /* Check multiple copy operations */
772 : 3 : memset(buf, 0, sizeof(buf));
773 : 3 : memset(tmp[0], 0, sizeof(tmp[0]));
774 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
775 : 3 : memset(expected, 0xa5, sizeof(expected));
776 : 3 : seq = NULL;
777 : 3 : completed = 0;
778 : :
779 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], sizeof(tmp[0]), NULL, NULL, 0xa5,
780 : : ut_sequence_step_cb, &completed);
781 : 3 : CU_ASSERT_EQUAL(rc, 0);
782 : :
783 : 3 : dst_iovs[0].iov_base = tmp[1];
784 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
785 : 3 : src_iovs[0].iov_base = tmp[0];
786 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
787 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
788 : 1 : &src_iovs[0], 1, NULL, NULL,
789 : : ut_sequence_step_cb, &completed);
790 : 3 : CU_ASSERT_EQUAL(rc, 0);
791 : :
792 : 3 : dst_iovs[1].iov_base = buf;
793 : 3 : dst_iovs[1].iov_len = sizeof(buf);
794 : 3 : src_iovs[1].iov_base = tmp[1];
795 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
796 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
797 : 1 : &src_iovs[1], 1, NULL, NULL,
798 : : ut_sequence_step_cb, &completed);
799 : 3 : CU_ASSERT_EQUAL(rc, 0);
800 : :
801 : 3 : ut_seq.complete = false;
802 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
803 : :
804 : 3 : poll_threads();
805 : 3 : CU_ASSERT_EQUAL(completed, 3);
806 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
807 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
808 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
809 : :
810 : : /* Check that adding a copy operation at the end will change destination buffer */
811 : 3 : memset(buf, 0, sizeof(buf));
812 : 3 : memset(tmp[0], 0, sizeof(tmp[0]));
813 : 3 : memset(expected, 0xa5, sizeof(buf));
814 : 3 : seq = NULL;
815 : 3 : completed = 0;
816 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], sizeof(tmp[0]), NULL, NULL, 0xa5,
817 : : ut_sequence_step_cb, &completed);
818 : 3 : CU_ASSERT_EQUAL(rc, 0);
819 : :
820 : 3 : dst_iovs[0].iov_base = buf;
821 : 3 : dst_iovs[0].iov_len = sizeof(buf);
822 : 3 : src_iovs[0].iov_base = tmp[0];
823 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
824 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
825 : 1 : &src_iovs[0], 1, NULL, NULL,
826 : : ut_sequence_step_cb, &completed);
827 : 3 : CU_ASSERT_EQUAL(rc, 0);
828 : :
829 : 3 : ut_seq.complete = false;
830 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
831 : :
832 : 3 : poll_threads();
833 : 3 : CU_ASSERT_EQUAL(completed, 2);
834 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
835 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
836 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
837 : :
838 : : /* Check that it's also possible to add copy operation at the beginning */
839 : 3 : memset(buf, 0, sizeof(buf));
840 : 3 : memset(tmp[0], 0xde, sizeof(tmp[0]));
841 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
842 : 3 : memset(expected, 0xa5, sizeof(expected));
843 : 3 : seq = NULL;
844 : 3 : completed = 0;
845 : :
846 : 3 : dst_iovs[0].iov_base = tmp[1];
847 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
848 : 3 : src_iovs[0].iov_base = tmp[0];
849 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
850 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
851 : 1 : &src_iovs[0], 1, NULL, NULL,
852 : : ut_sequence_step_cb, &completed);
853 : 3 : CU_ASSERT_EQUAL(rc, 0);
854 : :
855 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], sizeof(tmp[1]), NULL, NULL, 0xa5,
856 : : ut_sequence_step_cb, &completed);
857 : 3 : CU_ASSERT_EQUAL(rc, 0);
858 : :
859 : 3 : dst_iovs[1].iov_base = buf;
860 : 3 : dst_iovs[1].iov_len = sizeof(buf);
861 : 3 : src_iovs[1].iov_base = tmp[1];
862 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
863 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
864 : 1 : &src_iovs[1], 1, NULL, NULL,
865 : : ut_sequence_step_cb, &completed);
866 : 3 : CU_ASSERT_EQUAL(rc, 0);
867 : :
868 : 3 : ut_seq.complete = false;
869 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
870 : :
871 : 3 : poll_threads();
872 : 3 : CU_ASSERT_EQUAL(completed, 3);
873 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
874 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
875 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
876 : :
877 : 3 : spdk_put_io_channel(ioch);
878 : 3 : poll_threads();
879 : 3 : }
880 : :
881 : : static void
882 : 3 : test_sequence_abort(void)
883 : : {
884 : 3 : struct spdk_accel_sequence *seq = NULL;
885 : : struct spdk_io_channel *ioch;
886 : 2 : char buf[4096], tmp[2][4096], expected[4096];
887 : 2 : struct iovec src_iovs[2], dst_iovs[2];
888 : 2 : int rc, completed;
889 : :
890 : 3 : ioch = spdk_accel_get_io_channel();
891 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
892 : :
893 : : /* Check that aborting a sequence calls operation's callback, the operation is not executed
894 : : * and the sequence is freed
895 : : */
896 : 3 : memset(buf, 0, sizeof(buf));
897 : 3 : memset(expected, 0, sizeof(buf));
898 : 3 : completed = 0;
899 : 3 : seq = NULL;
900 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, sizeof(buf), NULL, NULL, 0xa5,
901 : : ut_sequence_step_cb, &completed);
902 : 3 : CU_ASSERT_EQUAL(rc, 0);
903 : :
904 : 3 : spdk_accel_sequence_abort(seq);
905 : 3 : CU_ASSERT_EQUAL(completed, 1);
906 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
907 : :
908 : : /* Check sequence with multiple operations */
909 : 3 : memset(buf, 0, sizeof(buf));
910 : 3 : memset(expected, 0, sizeof(buf));
911 : 3 : completed = 0;
912 : 3 : seq = NULL;
913 : :
914 : 3 : dst_iovs[0].iov_base = tmp[1];
915 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
916 : 3 : src_iovs[0].iov_base = tmp[0];
917 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
918 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
919 : 1 : &src_iovs[0], 1, NULL, NULL,
920 : : ut_sequence_step_cb, &completed);
921 : 3 : CU_ASSERT_EQUAL(rc, 0);
922 : :
923 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 4096, NULL, NULL, 0xa5,
924 : : ut_sequence_step_cb, &completed);
925 : 3 : CU_ASSERT_EQUAL(rc, 0);
926 : :
927 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 2048, NULL, NULL, 0xde,
928 : : ut_sequence_step_cb, &completed);
929 : 3 : CU_ASSERT_EQUAL(rc, 0);
930 : :
931 : 3 : dst_iovs[1].iov_base = buf;
932 : 3 : dst_iovs[1].iov_len = sizeof(buf);
933 : 3 : src_iovs[1].iov_base = tmp[1];
934 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
935 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
936 : 1 : &src_iovs[1], 1, NULL, NULL,
937 : : ut_sequence_step_cb, &completed);
938 : 3 : CU_ASSERT_EQUAL(rc, 0);
939 : :
940 : 3 : spdk_accel_sequence_abort(seq);
941 : 3 : CU_ASSERT_EQUAL(completed, 4);
942 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
943 : :
944 : : /* This should be a no-op */
945 : 3 : spdk_accel_sequence_abort(NULL);
946 : :
947 : 3 : spdk_put_io_channel(ioch);
948 : 3 : poll_threads();
949 : 3 : }
950 : :
951 : : static void
952 : 3 : test_sequence_append_error(void)
953 : : {
954 : 3 : struct spdk_accel_sequence *seq = NULL;
955 : : struct spdk_io_channel *ioch;
956 : : struct accel_io_channel *accel_ch;
957 : 2 : struct iovec src_iovs, dst_iovs;
958 : 2 : char buf[4096];
959 : 3 : STAILQ_HEAD(, spdk_accel_task) tasks = STAILQ_HEAD_INITIALIZER(tasks);
960 : 3 : SLIST_HEAD(, spdk_accel_sequence) seqs = SLIST_HEAD_INITIALIZER(seqs);
961 : : int rc;
962 : :
963 : 3 : ioch = spdk_accel_get_io_channel();
964 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
965 : 3 : accel_ch = spdk_io_channel_get_ctx(ioch);
966 : :
967 : : /* Check that append fails and no sequence object is allocated when there are no more free
968 : : * tasks */
969 [ + + + + ]: 3 : STAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task);
970 : :
971 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, sizeof(buf), NULL, NULL, 0xa5,
972 : : ut_sequence_step_cb, NULL);
973 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
974 : 3 : CU_ASSERT_PTR_NULL(seq);
975 : :
976 : 3 : dst_iovs.iov_base = buf;
977 : 3 : dst_iovs.iov_len = 2048;
978 : 3 : src_iovs.iov_base = &buf[2048];
979 : 3 : src_iovs.iov_len = 2048;
980 : 3 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs, 1, NULL, NULL,
981 : : &src_iovs, 1, NULL, NULL, ut_sequence_step_cb, NULL);
982 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
983 : 3 : CU_ASSERT_PTR_NULL(seq);
984 : :
985 : 3 : dst_iovs.iov_base = buf;
986 : 3 : dst_iovs.iov_len = 2048;
987 : 3 : src_iovs.iov_base = &buf[2048];
988 : 3 : src_iovs.iov_len = 2048;
989 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
990 : : &src_iovs, 1, NULL, NULL, ut_sequence_step_cb, NULL);
991 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
992 : 3 : CU_ASSERT_PTR_NULL(seq);
993 : :
994 : : /* Check that the same happens when the sequence queue is empty */
995 [ + + + + ]: 3 : STAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task);
996 : 3 : SLIST_SWAP(&seqs, &accel_ch->seq_pool, spdk_accel_sequence);
997 : :
998 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, sizeof(buf), NULL, NULL, 0xa5,
999 : : ut_sequence_step_cb, NULL);
1000 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
1001 : 3 : CU_ASSERT_PTR_NULL(seq);
1002 : :
1003 : 3 : dst_iovs.iov_base = buf;
1004 : 3 : dst_iovs.iov_len = 2048;
1005 : 3 : src_iovs.iov_base = &buf[2048];
1006 : 3 : src_iovs.iov_len = 2048;
1007 : 3 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1008 : : &src_iovs, 1, NULL, NULL, ut_sequence_step_cb, NULL);
1009 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
1010 : 3 : CU_ASSERT_PTR_NULL(seq);
1011 : :
1012 : 3 : dst_iovs.iov_base = buf;
1013 : 3 : dst_iovs.iov_len = 2048;
1014 : 3 : src_iovs.iov_base = &buf[2048];
1015 : 3 : src_iovs.iov_len = 2048;
1016 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1017 : : &src_iovs, 1, NULL, NULL, ut_sequence_step_cb, NULL);
1018 : 3 : CU_ASSERT_EQUAL(rc, -ENOMEM);
1019 : 3 : CU_ASSERT_PTR_NULL(seq);
1020 : :
1021 [ + + + + ]: 3 : STAILQ_SWAP(&tasks, &accel_ch->task_pool, spdk_accel_task);
1022 : :
1023 : 3 : spdk_put_io_channel(ioch);
1024 : 3 : poll_threads();
1025 : 3 : }
1026 : :
1027 : : struct ut_sequence_operation {
1028 : : int complete_status;
1029 : : int submit_status;
1030 : : int count;
1031 : : struct iovec *src_iovs;
1032 : : uint32_t src_iovcnt;
1033 : : struct spdk_memory_domain *src_domain;
1034 : : void *src_domain_ctx;
1035 : : struct iovec *dst_iovs;
1036 : : uint32_t dst_iovcnt;
1037 : : struct spdk_memory_domain *dst_domain;
1038 : : void *dst_domain_ctx;
1039 : : int (*submit)(struct spdk_io_channel *ch, struct spdk_accel_task *t);
1040 : : };
1041 : :
1042 : : static struct ut_sequence_operation g_seq_operations[SPDK_ACCEL_OPC_LAST];
1043 : :
1044 : : static int
1045 : 234 : ut_sequence_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *task)
1046 : : {
1047 : 234 : struct ut_sequence_operation *op = &g_seq_operations[task->op_code];
1048 : :
1049 : 234 : op->count++;
1050 [ + + ]: 234 : if (op->submit != NULL) {
1051 : 174 : return op->submit(ch, task);
1052 : : }
1053 [ + + ]: 60 : if (op->src_iovs != NULL) {
1054 : 27 : CU_ASSERT_EQUAL(task->s.iovcnt, op->src_iovcnt);
1055 [ - + - + ]: 27 : CU_ASSERT_EQUAL(memcmp(task->s.iovs, op->src_iovs,
1056 : : sizeof(struct iovec) * op->src_iovcnt), 0);
1057 : 9 : }
1058 [ + + ]: 60 : if (op->dst_iovs != NULL) {
1059 : 30 : CU_ASSERT_EQUAL(task->d.iovcnt, op->dst_iovcnt);
1060 [ - + - + ]: 30 : CU_ASSERT_EQUAL(memcmp(task->d.iovs, op->dst_iovs,
1061 : : sizeof(struct iovec) * op->dst_iovcnt), 0);
1062 : 10 : }
1063 : :
1064 : 60 : CU_ASSERT_EQUAL(task->src_domain, op->src_domain);
1065 : 60 : CU_ASSERT_EQUAL(task->dst_domain, op->dst_domain);
1066 [ + + ]: 60 : if (op->src_domain != NULL) {
1067 : 3 : CU_ASSERT_EQUAL(task->src_domain_ctx, op->src_domain_ctx);
1068 : 1 : }
1069 [ + + ]: 60 : if (op->dst_domain != NULL) {
1070 : 3 : CU_ASSERT_EQUAL(task->dst_domain_ctx, op->dst_domain_ctx);
1071 : 1 : }
1072 : :
1073 [ + + ]: 60 : if (op->submit_status != 0) {
1074 : 6 : return op->submit_status;
1075 : : }
1076 : :
1077 : 54 : spdk_accel_task_complete(task, op->complete_status);
1078 : :
1079 : 54 : return 0;
1080 : 78 : }
1081 : :
1082 : : static void
1083 : 30 : ut_clear_operations(void)
1084 : : {
1085 [ - + ]: 30 : memset(&g_seq_operations, 0, sizeof(g_seq_operations));
1086 : 30 : }
1087 : :
1088 : : static void
1089 : 3 : test_sequence_completion_error(void)
1090 : : {
1091 : 3 : struct spdk_accel_sequence *seq = NULL;
1092 : : struct spdk_io_channel *ioch;
1093 : 2 : struct ut_sequence ut_seq;
1094 : 2 : struct iovec src_iovs, dst_iovs;
1095 : 2 : char buf[4096], tmp[4096];
1096 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
1097 : 2 : int i, rc, completed;
1098 : :
1099 : 3 : ioch = spdk_accel_get_io_channel();
1100 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
1101 : :
1102 : : /* Override the submit_tasks function */
1103 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
1104 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
1105 : 51 : modules[i] = g_modules_opc[i];
1106 : 51 : g_modules_opc[i] = g_module;
1107 : 17 : }
1108 : :
1109 [ - + ]: 3 : memset(buf, 0, sizeof(buf));
1110 [ - + ]: 3 : memset(tmp, 0, sizeof(tmp));
1111 : :
1112 : : /* Check that if the first operation completes with an error, the whole sequence is
1113 : : * completed with that error and that all operations' completion callbacks are executed
1114 : : */
1115 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].complete_status = -E2BIG;
1116 : 3 : completed = 0;
1117 : 3 : seq = NULL;
1118 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp, sizeof(tmp), NULL, NULL, 0xa5,
1119 : : ut_sequence_step_cb, &completed);
1120 : 3 : CU_ASSERT_EQUAL(rc, 0);
1121 : :
1122 : 3 : dst_iovs.iov_base = buf;
1123 : 3 : dst_iovs.iov_len = sizeof(buf);
1124 : 3 : src_iovs.iov_base = tmp;
1125 : 3 : src_iovs.iov_len = sizeof(tmp);
1126 : :
1127 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1128 : : &src_iovs, 1, NULL, NULL,
1129 : : ut_sequence_step_cb, &completed);
1130 : 3 : CU_ASSERT_EQUAL(rc, 0);
1131 : :
1132 : 3 : ut_seq.complete = false;
1133 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1134 : :
1135 : 3 : poll_threads();
1136 : 3 : CU_ASSERT_EQUAL(completed, 2);
1137 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -E2BIG);
1138 : :
1139 : : /* Check the same with a second operation in the sequence */
1140 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].complete_status = -EACCES;
1141 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].complete_status = 0;
1142 : 3 : completed = 0;
1143 : 3 : seq = NULL;
1144 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp, sizeof(tmp), NULL, NULL, 0xa5,
1145 : : ut_sequence_step_cb, &completed);
1146 : 3 : CU_ASSERT_EQUAL(rc, 0);
1147 : :
1148 : 3 : dst_iovs.iov_base = buf;
1149 : 3 : dst_iovs.iov_len = sizeof(buf);
1150 : 3 : src_iovs.iov_base = tmp;
1151 : 3 : src_iovs.iov_len = sizeof(tmp);
1152 : :
1153 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1154 : : &src_iovs, 1, NULL, NULL,
1155 : : ut_sequence_step_cb, &completed);
1156 : 3 : CU_ASSERT_EQUAL(rc, 0);
1157 : :
1158 : 3 : ut_seq.complete = false;
1159 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1160 : :
1161 : 3 : poll_threads();
1162 : 3 : CU_ASSERT_EQUAL(completed, 2);
1163 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EACCES);
1164 : :
1165 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].complete_status = 0;
1166 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].complete_status = 0;
1167 : :
1168 : : /* Check submission failure of the first operation */
1169 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].submit_status = -EADDRINUSE;
1170 : 3 : completed = 0;
1171 : 3 : seq = NULL;
1172 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp, sizeof(tmp), NULL, NULL, 0xa5,
1173 : : ut_sequence_step_cb, &completed);
1174 : 3 : CU_ASSERT_EQUAL(rc, 0);
1175 : :
1176 : 3 : dst_iovs.iov_base = buf;
1177 : 3 : dst_iovs.iov_len = sizeof(buf);
1178 : 3 : src_iovs.iov_base = tmp;
1179 : 3 : src_iovs.iov_len = sizeof(tmp);
1180 : :
1181 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1182 : : &src_iovs, 1, NULL, NULL,
1183 : : ut_sequence_step_cb, &completed);
1184 : 3 : CU_ASSERT_EQUAL(rc, 0);
1185 : :
1186 : 3 : ut_seq.complete = false;
1187 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1188 : :
1189 : 3 : poll_threads();
1190 : 3 : CU_ASSERT_EQUAL(completed, 2);
1191 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EADDRINUSE);
1192 : :
1193 : : /* Check the same with a second operation */
1194 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].submit_status = -EADDRNOTAVAIL;
1195 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].submit_status = 0;
1196 : 3 : completed = 0;
1197 : 3 : seq = NULL;
1198 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp, sizeof(tmp), NULL, NULL, 0xa5,
1199 : : ut_sequence_step_cb, &completed);
1200 : 3 : CU_ASSERT_EQUAL(rc, 0);
1201 : :
1202 : 3 : dst_iovs.iov_base = buf;
1203 : 3 : dst_iovs.iov_len = sizeof(buf);
1204 : 3 : src_iovs.iov_base = tmp;
1205 : 3 : src_iovs.iov_len = sizeof(tmp);
1206 : :
1207 : 3 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs, 1, NULL, NULL,
1208 : : &src_iovs, 1, NULL, NULL,
1209 : : ut_sequence_step_cb, &completed);
1210 : 3 : CU_ASSERT_EQUAL(rc, 0);
1211 : :
1212 : 3 : ut_seq.complete = false;
1213 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1214 : :
1215 : 3 : poll_threads();
1216 : 3 : CU_ASSERT_EQUAL(completed, 2);
1217 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EADDRNOTAVAIL);
1218 : :
1219 : : /* Cleanup module pointers to make subsequent tests work correctly */
1220 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
1221 : 51 : g_modules_opc[i] = modules[i];
1222 : 17 : }
1223 : :
1224 : 3 : ut_clear_operations();
1225 : 3 : spdk_put_io_channel(ioch);
1226 : 3 : poll_threads();
1227 : 3 : }
1228 : :
1229 : : #ifdef SPDK_CONFIG_ISAL
1230 : : static void
1231 : 6 : ut_compress_cb(void *cb_arg, int status)
1232 : : {
1233 : 6 : int *completed = cb_arg;
1234 : :
1235 : 6 : CU_ASSERT_EQUAL(status, 0);
1236 : :
1237 : 6 : *completed = 1;
1238 : 6 : }
1239 : :
1240 : : static void
1241 : 3 : test_sequence_decompress(void)
1242 : : {
1243 : 3 : struct spdk_accel_sequence *seq = NULL;
1244 : : struct spdk_io_channel *ioch;
1245 : 2 : struct ut_sequence ut_seq;
1246 : 2 : char buf[4096], tmp[2][4096], expected[4096];
1247 : 2 : struct iovec src_iovs[2], dst_iovs[2];
1248 : 2 : uint32_t compressed_size;
1249 : 3 : int rc, completed = 0;
1250 : :
1251 : 3 : ioch = spdk_accel_get_io_channel();
1252 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
1253 : :
1254 : 3 : memset(expected, 0xa5, sizeof(expected));
1255 : 3 : src_iovs[0].iov_base = expected;
1256 : 3 : src_iovs[0].iov_len = sizeof(expected);
1257 : 3 : rc = spdk_accel_submit_compress(ioch, tmp[0], sizeof(tmp[0]), &src_iovs[0], 1,
1258 : : &compressed_size, ut_compress_cb, &completed);
1259 : 3 : CU_ASSERT_EQUAL(rc, 0);
1260 : :
1261 [ + + ]: 6 : while (!completed) {
1262 : 3 : poll_threads();
1263 : : }
1264 : :
1265 : : /* Check a single decompress operation in a sequence */
1266 : 3 : seq = NULL;
1267 : 3 : completed = 0;
1268 : :
1269 : 3 : dst_iovs[0].iov_base = buf;
1270 : 3 : dst_iovs[0].iov_len = sizeof(buf);
1271 : 3 : src_iovs[0].iov_base = tmp[0];
1272 : 3 : src_iovs[0].iov_len = compressed_size;
1273 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1274 : 1 : &src_iovs[0], 1, NULL, NULL,
1275 : : ut_sequence_step_cb, &completed);
1276 : 3 : CU_ASSERT_EQUAL(rc, 0);
1277 : :
1278 : 3 : ut_seq.complete = false;
1279 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1280 : :
1281 : 3 : poll_threads();
1282 : :
1283 : 3 : CU_ASSERT_EQUAL(completed, 1);
1284 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1285 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1286 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1287 : :
1288 : : /* Put the decompress operation in the middle of a sequence with a copy operation at the
1289 : : * beginning and a fill at the end modifying the first 2048B of the buffer.
1290 : : */
1291 : 3 : memset(expected, 0xfe, 2048);
1292 : 3 : memset(buf, 0, sizeof(buf));
1293 : 3 : seq = NULL;
1294 : 3 : completed = 0;
1295 : :
1296 : 3 : dst_iovs[0].iov_base = tmp[1];
1297 : 3 : dst_iovs[0].iov_len = compressed_size;
1298 : 3 : src_iovs[0].iov_base = tmp[0];
1299 : 3 : src_iovs[0].iov_len = compressed_size;
1300 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1301 : 1 : &src_iovs[0], 1, NULL, NULL,
1302 : : ut_sequence_step_cb, &completed);
1303 : 3 : CU_ASSERT_EQUAL(rc, 0);
1304 : :
1305 : 3 : dst_iovs[1].iov_base = buf;
1306 : 3 : dst_iovs[1].iov_len = sizeof(buf);
1307 : 3 : src_iovs[1].iov_base = tmp[1];
1308 : 3 : src_iovs[1].iov_len = compressed_size;
1309 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1310 : 1 : &src_iovs[1], 1, NULL, NULL,
1311 : : ut_sequence_step_cb, &completed);
1312 : 3 : CU_ASSERT_EQUAL(rc, 0);
1313 : :
1314 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 2048, NULL, NULL, 0xfe,
1315 : : ut_sequence_step_cb, &completed);
1316 : 3 : CU_ASSERT_EQUAL(rc, 0);
1317 : :
1318 : 3 : ut_seq.complete = false;
1319 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1320 : :
1321 : 3 : poll_threads();
1322 : :
1323 : 3 : CU_ASSERT_EQUAL(completed, 3);
1324 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1325 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1326 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1327 : :
1328 : : /* Check sequence with decompress at the beginning: decompress -> copy */
1329 : 3 : memset(expected, 0xa5, sizeof(expected));
1330 : 3 : memset(buf, 0, sizeof(buf));
1331 : 3 : seq = NULL;
1332 : 3 : completed = 0;
1333 : :
1334 : 3 : dst_iovs[0].iov_base = tmp[1];
1335 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1336 : 3 : src_iovs[0].iov_base = tmp[0];
1337 : 3 : src_iovs[0].iov_len = compressed_size;
1338 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1339 : 1 : &src_iovs[0], 1, NULL, NULL,
1340 : : ut_sequence_step_cb, &completed);
1341 : 3 : CU_ASSERT_EQUAL(rc, 0);
1342 : :
1343 : 3 : dst_iovs[1].iov_base = buf;
1344 : 3 : dst_iovs[1].iov_len = sizeof(buf);
1345 : 3 : src_iovs[1].iov_base = tmp[1];
1346 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1347 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1348 : 1 : &src_iovs[1], 1, NULL, NULL,
1349 : : ut_sequence_step_cb, &completed);
1350 : 3 : CU_ASSERT_EQUAL(rc, 0);
1351 : :
1352 : 3 : ut_seq.complete = false;
1353 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1354 : :
1355 : 3 : poll_threads();
1356 : :
1357 : 3 : CU_ASSERT_EQUAL(completed, 2);
1358 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1359 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1360 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1361 : :
1362 : 3 : spdk_put_io_channel(ioch);
1363 : 3 : poll_threads();
1364 : 3 : }
1365 : :
1366 : : static void
1367 : 3 : test_sequence_reverse(void)
1368 : : {
1369 : 3 : struct spdk_accel_sequence *seq = NULL;
1370 : : struct spdk_io_channel *ioch;
1371 : 2 : struct ut_sequence ut_seq;
1372 : 2 : char buf[4096], tmp[2][4096], expected[4096];
1373 : 2 : struct iovec src_iovs[2], dst_iovs[2];
1374 : 2 : uint32_t compressed_size;
1375 : 3 : int rc, completed = 0;
1376 : :
1377 : 3 : ioch = spdk_accel_get_io_channel();
1378 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
1379 : :
1380 : 3 : memset(expected, 0xa5, sizeof(expected));
1381 : 3 : src_iovs[0].iov_base = expected;
1382 : 3 : src_iovs[0].iov_len = sizeof(expected);
1383 : 3 : rc = spdk_accel_submit_compress(ioch, tmp[0], sizeof(tmp[0]), &src_iovs[0], 1,
1384 : : &compressed_size, ut_compress_cb, &completed);
1385 : 3 : CU_ASSERT_EQUAL(rc, 0);
1386 : :
1387 [ + + ]: 6 : while (!completed) {
1388 : 3 : poll_threads();
1389 : : }
1390 : :
1391 : : /* First check that reversing a sequence with a single operation is a no-op */
1392 : 3 : memset(buf, 0, sizeof(buf));
1393 : 3 : seq = NULL;
1394 : 3 : completed = 0;
1395 : :
1396 : 3 : dst_iovs[0].iov_base = buf;
1397 : 3 : dst_iovs[0].iov_len = sizeof(buf);
1398 : 3 : src_iovs[0].iov_base = tmp[0];
1399 : 3 : src_iovs[0].iov_len = compressed_size;
1400 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1401 : 1 : &src_iovs[0], 1, NULL, NULL,
1402 : : ut_sequence_step_cb, &completed);
1403 : 3 : CU_ASSERT_EQUAL(rc, 0);
1404 : :
1405 : 3 : spdk_accel_sequence_reverse(seq);
1406 : :
1407 : 3 : ut_seq.complete = false;
1408 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1409 : :
1410 : 3 : poll_threads();
1411 : :
1412 : 3 : CU_ASSERT_EQUAL(completed, 1);
1413 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1414 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1415 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1416 : :
1417 : : /* Add a copy operation at the end with src set to the compressed data. After reverse(),
1418 : : * that copy operation should be first, so decompress() should receive compressed data in
1419 : : * its src buffer.
1420 : : */
1421 : 3 : memset(buf, 0, sizeof(buf));
1422 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
1423 : 3 : seq = NULL;
1424 : 3 : completed = 0;
1425 : :
1426 : 3 : dst_iovs[0].iov_base = buf;
1427 : 3 : dst_iovs[0].iov_len = sizeof(buf);
1428 : 3 : src_iovs[0].iov_base = tmp[1];
1429 : 3 : src_iovs[0].iov_len = compressed_size;
1430 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1431 : 1 : &src_iovs[0], 1, NULL, NULL,
1432 : : ut_sequence_step_cb, &completed);
1433 : 3 : CU_ASSERT_EQUAL(rc, 0);
1434 : :
1435 : 3 : dst_iovs[1].iov_base = tmp[1];
1436 : 3 : dst_iovs[1].iov_len = compressed_size;
1437 : 3 : src_iovs[1].iov_base = tmp[0];
1438 : 3 : src_iovs[1].iov_len = compressed_size;
1439 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1440 : 1 : &src_iovs[1], 1, NULL, NULL,
1441 : : ut_sequence_step_cb, &completed);
1442 : 3 : CU_ASSERT_EQUAL(rc, 0);
1443 : :
1444 : 3 : spdk_accel_sequence_reverse(seq);
1445 : :
1446 : 3 : ut_seq.complete = false;
1447 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1448 : :
1449 : 3 : poll_threads();
1450 : :
1451 : 3 : CU_ASSERT_EQUAL(completed, 2);
1452 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1453 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1454 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1455 : :
1456 : : /* Check the same, but add an extra fill operation at the beginning that should execute last
1457 : : * after reverse().
1458 : : */
1459 : 3 : memset(buf, 0, sizeof(buf));
1460 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
1461 : 3 : memset(expected, 0xfe, 2048);
1462 : 3 : seq = NULL;
1463 : 3 : completed = 0;
1464 : :
1465 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 2048, NULL, NULL, 0xfe,
1466 : : ut_sequence_step_cb, &completed);
1467 : 3 : CU_ASSERT_EQUAL(rc, 0);
1468 : :
1469 : 3 : dst_iovs[0].iov_base = buf;
1470 : 3 : dst_iovs[0].iov_len = sizeof(buf);
1471 : 3 : src_iovs[0].iov_base = tmp[1];
1472 : 3 : src_iovs[0].iov_len = compressed_size;
1473 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1474 : 1 : &src_iovs[0], 1, NULL, NULL,
1475 : : ut_sequence_step_cb, &completed);
1476 : 3 : CU_ASSERT_EQUAL(rc, 0);
1477 : :
1478 : 3 : dst_iovs[1].iov_base = tmp[1];
1479 : 3 : dst_iovs[1].iov_len = compressed_size;
1480 : 3 : src_iovs[1].iov_base = tmp[0];
1481 : 3 : src_iovs[1].iov_len = compressed_size;
1482 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1483 : 1 : &src_iovs[1], 1, NULL, NULL,
1484 : : ut_sequence_step_cb, &completed);
1485 : 3 : CU_ASSERT_EQUAL(rc, 0);
1486 : :
1487 : 3 : spdk_accel_sequence_reverse(seq);
1488 : :
1489 : 3 : ut_seq.complete = false;
1490 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1491 : :
1492 : 3 : poll_threads();
1493 : :
1494 : 3 : CU_ASSERT_EQUAL(completed, 3);
1495 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1496 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1497 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1498 : :
1499 : : /* Build the sequence in order and then reverse it twice */
1500 : 3 : memset(buf, 0, sizeof(buf));
1501 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
1502 : 3 : seq = NULL;
1503 : 3 : completed = 0;
1504 : :
1505 : 3 : dst_iovs[0].iov_base = tmp[1];
1506 : 3 : dst_iovs[0].iov_len = compressed_size;
1507 : 3 : src_iovs[0].iov_base = tmp[0];
1508 : 3 : src_iovs[0].iov_len = compressed_size;
1509 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1510 : 1 : &src_iovs[0], 1, NULL, NULL,
1511 : : ut_sequence_step_cb, &completed);
1512 : 3 : CU_ASSERT_EQUAL(rc, 0);
1513 : :
1514 : 3 : dst_iovs[1].iov_base = buf;
1515 : 3 : dst_iovs[1].iov_len = sizeof(buf);
1516 : 3 : src_iovs[1].iov_base = tmp[1];
1517 : 3 : src_iovs[1].iov_len = compressed_size;
1518 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1519 : 1 : &src_iovs[1], 1, NULL, NULL,
1520 : : ut_sequence_step_cb, &completed);
1521 : 3 : CU_ASSERT_EQUAL(rc, 0);
1522 : :
1523 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 2048, NULL, NULL, 0xfe,
1524 : : ut_sequence_step_cb, &completed);
1525 : 3 : CU_ASSERT_EQUAL(rc, 0);
1526 : :
1527 : 3 : spdk_accel_sequence_reverse(seq);
1528 : 3 : spdk_accel_sequence_reverse(seq);
1529 : :
1530 : 3 : ut_seq.complete = false;
1531 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1532 : :
1533 : 3 : poll_threads();
1534 : :
1535 : 3 : CU_ASSERT_EQUAL(completed, 3);
1536 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1537 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1538 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
1539 : :
1540 : 3 : spdk_put_io_channel(ioch);
1541 : 3 : poll_threads();
1542 : 3 : }
1543 : : #endif
1544 : :
1545 : : static void
1546 : 3 : test_sequence_copy_elision(void)
1547 : : {
1548 : 3 : struct spdk_accel_sequence *seq = NULL;
1549 : : struct spdk_io_channel *ioch;
1550 : 2 : struct ut_sequence ut_seq;
1551 : 2 : struct iovec src_iovs[4], dst_iovs[4], exp_iovs[2];
1552 : 2 : char buf[4096], tmp[4][4096];
1553 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
1554 : 3 : struct spdk_accel_crypto_key key = {};
1555 : 2 : int i, rc, completed;
1556 : :
1557 : 3 : ioch = spdk_accel_get_io_channel();
1558 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
1559 : :
1560 : : /* Override the submit_tasks function */
1561 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
1562 : 3 : g_module.supports_memory_domains = true;
1563 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
1564 : 51 : g_seq_operations[i].complete_status = 0;
1565 : 51 : g_seq_operations[i].submit_status = 0;
1566 : 51 : g_seq_operations[i].count = 0;
1567 : :
1568 : 51 : modules[i] = g_modules_opc[i];
1569 : 51 : g_modules_opc[i] = g_module;
1570 : 17 : }
1571 : :
1572 : : /* Check that a copy operation at the beginning is removed */
1573 : 3 : seq = NULL;
1574 : 3 : completed = 0;
1575 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].dst_iovcnt = 1;
1576 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].src_iovcnt = 1;
1577 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].src_iovs = &exp_iovs[0];
1578 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].dst_iovs = &exp_iovs[1];
1579 : 3 : exp_iovs[0].iov_base = tmp[0];
1580 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1581 : 3 : exp_iovs[1].iov_base = buf;
1582 : 3 : exp_iovs[1].iov_len = 2048;
1583 : :
1584 : 3 : dst_iovs[0].iov_base = tmp[1];
1585 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1586 : 3 : src_iovs[0].iov_base = tmp[0];
1587 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1588 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1589 : 1 : &src_iovs[0], 1, NULL, NULL,
1590 : : ut_sequence_step_cb, &completed);
1591 : 3 : CU_ASSERT_EQUAL(rc, 0);
1592 : :
1593 : 3 : dst_iovs[1].iov_base = buf;
1594 : 3 : dst_iovs[1].iov_len = 2048;
1595 : 3 : src_iovs[1].iov_base = tmp[1];
1596 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1597 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1598 : 1 : &src_iovs[1], 1, NULL, NULL,
1599 : : ut_sequence_step_cb, &completed);
1600 : 3 : CU_ASSERT_EQUAL(rc, 0);
1601 : :
1602 : 3 : ut_seq.complete = false;
1603 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1604 : :
1605 : 3 : poll_threads();
1606 : :
1607 : 3 : CU_ASSERT_EQUAL(completed, 2);
1608 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1609 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1610 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1611 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
1612 : :
1613 : : /* Check that a copy operation at the end is removed too */
1614 : 3 : seq = NULL;
1615 : 3 : completed = 0;
1616 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1617 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
1618 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].src_iovs = &exp_iovs[0];
1619 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].dst_iovs = &exp_iovs[1];
1620 : 3 : exp_iovs[0].iov_base = tmp[0];
1621 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1622 : 3 : exp_iovs[1].iov_base = buf;
1623 : 3 : exp_iovs[1].iov_len = 2048;
1624 : :
1625 : 3 : dst_iovs[0].iov_base = tmp[1];
1626 : 3 : dst_iovs[0].iov_len = 2048;
1627 : 3 : src_iovs[0].iov_base = tmp[0];
1628 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1629 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1630 : 1 : &src_iovs[0], 1, NULL, NULL,
1631 : : ut_sequence_step_cb, &completed);
1632 : 3 : CU_ASSERT_EQUAL(rc, 0);
1633 : :
1634 : 3 : dst_iovs[1].iov_base = buf;
1635 : 3 : dst_iovs[1].iov_len = 2048;
1636 : 3 : src_iovs[1].iov_base = tmp[1];
1637 : 3 : src_iovs[1].iov_len = 2048;
1638 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1639 : 1 : &src_iovs[1], 1, NULL, NULL,
1640 : : ut_sequence_step_cb, &completed);
1641 : 3 : CU_ASSERT_EQUAL(rc, 0);
1642 : :
1643 : 3 : ut_seq.complete = false;
1644 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1645 : :
1646 : 3 : poll_threads();
1647 : :
1648 : 3 : CU_ASSERT_EQUAL(completed, 2);
1649 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1650 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1651 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1652 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
1653 : :
1654 : : /* Check a copy operation both at the beginning and the end */
1655 : 3 : seq = NULL;
1656 : 3 : completed = 0;
1657 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1658 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
1659 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].src_iovs = &exp_iovs[0];
1660 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].dst_iovs = &exp_iovs[1];
1661 : 3 : exp_iovs[0].iov_base = tmp[0];
1662 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1663 : 3 : exp_iovs[1].iov_base = buf;
1664 : 3 : exp_iovs[1].iov_len = 2048;
1665 : :
1666 : 3 : dst_iovs[0].iov_base = tmp[1];
1667 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1668 : 3 : src_iovs[0].iov_base = tmp[0];
1669 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1670 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1671 : 1 : &src_iovs[0], 1, NULL, NULL,
1672 : : ut_sequence_step_cb, &completed);
1673 : 3 : CU_ASSERT_EQUAL(rc, 0);
1674 : :
1675 : 3 : dst_iovs[1].iov_base = tmp[2];
1676 : 3 : dst_iovs[1].iov_len = 2048;
1677 : 3 : src_iovs[1].iov_base = tmp[1];
1678 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1679 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1680 : 1 : &src_iovs[1], 1, NULL, NULL,
1681 : : ut_sequence_step_cb, &completed);
1682 : 3 : CU_ASSERT_EQUAL(rc, 0);
1683 : :
1684 : 3 : dst_iovs[2].iov_base = buf;
1685 : 3 : dst_iovs[2].iov_len = 2048;
1686 : 3 : src_iovs[2].iov_base = tmp[2];
1687 : 3 : src_iovs[2].iov_len = 2048;
1688 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
1689 : 1 : &src_iovs[2], 1, NULL, NULL,
1690 : : ut_sequence_step_cb, &completed);
1691 : 3 : CU_ASSERT_EQUAL(rc, 0);
1692 : :
1693 : 3 : ut_seq.complete = false;
1694 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1695 : :
1696 : 3 : poll_threads();
1697 : :
1698 : 3 : CU_ASSERT_EQUAL(completed, 3);
1699 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1700 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1701 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1702 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
1703 : :
1704 : : /* Check decompress + copy + decompress + copy */
1705 : 3 : seq = NULL;
1706 : 3 : completed = 0;
1707 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1708 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
1709 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].src_iovs = NULL;
1710 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].dst_iovs = NULL;
1711 : :
1712 : 3 : dst_iovs[0].iov_base = tmp[1];
1713 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1714 : 3 : src_iovs[0].iov_base = tmp[0];
1715 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1716 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1717 : 1 : &src_iovs[0], 1, NULL, NULL,
1718 : : ut_sequence_step_cb, &completed);
1719 : 3 : CU_ASSERT_EQUAL(rc, 0);
1720 : :
1721 : 3 : dst_iovs[1].iov_base = tmp[2];
1722 : 3 : dst_iovs[1].iov_len = 2048;
1723 : 3 : src_iovs[1].iov_base = tmp[1];
1724 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1725 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1726 : 1 : &src_iovs[1], 1, NULL, NULL,
1727 : : ut_sequence_step_cb, &completed);
1728 : 3 : CU_ASSERT_EQUAL(rc, 0);
1729 : :
1730 : 3 : dst_iovs[2].iov_base = tmp[3];
1731 : 3 : dst_iovs[2].iov_len = 1024;
1732 : 3 : src_iovs[2].iov_base = tmp[2];
1733 : 3 : src_iovs[2].iov_len = 2048;
1734 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
1735 : 1 : &src_iovs[2], 1, NULL, NULL,
1736 : : ut_sequence_step_cb, &completed);
1737 : 3 : CU_ASSERT_EQUAL(rc, 0);
1738 : :
1739 : 3 : dst_iovs[3].iov_base = buf;
1740 : 3 : dst_iovs[3].iov_len = 1024;
1741 : 3 : src_iovs[3].iov_base = tmp[3];
1742 : 3 : src_iovs[3].iov_len = 1024;
1743 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[3], 1, NULL, NULL,
1744 : 1 : &src_iovs[3], 1, NULL, NULL,
1745 : : ut_sequence_step_cb, &completed);
1746 : 3 : CU_ASSERT_EQUAL(rc, 0);
1747 : :
1748 : 3 : ut_seq.complete = false;
1749 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1750 : :
1751 : 3 : poll_threads();
1752 : :
1753 : 3 : CU_ASSERT_EQUAL(completed, 4);
1754 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1755 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1756 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1757 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 2);
1758 : :
1759 : : /* Check two copy operations - one of them should be removed, while the other should be
1760 : : * executed normally */
1761 : 3 : seq = NULL;
1762 : 3 : completed = 0;
1763 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1764 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].dst_iovcnt = 1;
1765 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].src_iovcnt = 1;
1766 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].src_iovs = &exp_iovs[0];
1767 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].dst_iovs = &exp_iovs[1];
1768 : 3 : exp_iovs[0].iov_base = tmp[0];
1769 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1770 : 3 : exp_iovs[1].iov_base = buf;
1771 : 3 : exp_iovs[1].iov_len = sizeof(buf);
1772 : :
1773 : 3 : dst_iovs[0].iov_base = tmp[1];
1774 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1775 : 3 : src_iovs[0].iov_base = tmp[0];
1776 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1777 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1778 : 1 : &src_iovs[0], 1, NULL, NULL,
1779 : : ut_sequence_step_cb, &completed);
1780 : 3 : CU_ASSERT_EQUAL(rc, 0);
1781 : :
1782 : 3 : dst_iovs[1].iov_base = buf;
1783 : 3 : dst_iovs[1].iov_len = sizeof(buf);
1784 : 3 : src_iovs[1].iov_base = tmp[1];
1785 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1786 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
1787 : 1 : &src_iovs[1], 1, NULL, NULL,
1788 : : ut_sequence_step_cb, &completed);
1789 : 3 : CU_ASSERT_EQUAL(rc, 0);
1790 : :
1791 : 3 : ut_seq.complete = false;
1792 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1793 : :
1794 : 3 : poll_threads();
1795 : :
1796 : 3 : CU_ASSERT_EQUAL(completed, 2);
1797 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1798 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1799 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 1);
1800 : :
1801 : : /* Check fill + copy */
1802 : 3 : seq = NULL;
1803 : 3 : completed = 0;
1804 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1805 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].count = 0;
1806 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].src_iovs = NULL;
1807 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].dst_iovs = NULL;
1808 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].dst_iovcnt = 1;
1809 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].dst_iovs = &exp_iovs[0];
1810 : 3 : exp_iovs[0].iov_base = buf;
1811 : 3 : exp_iovs[0].iov_len = sizeof(buf);
1812 : :
1813 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], sizeof(tmp[0]), NULL, NULL, 0xa5,
1814 : : ut_sequence_step_cb, &completed);
1815 : 3 : CU_ASSERT_EQUAL(rc, 0);
1816 : :
1817 : 3 : dst_iovs[0].iov_base = buf;
1818 : 3 : dst_iovs[0].iov_len = sizeof(buf);
1819 : 3 : src_iovs[0].iov_base = tmp[0];
1820 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1821 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1822 : 1 : &src_iovs[0], 1, NULL, NULL,
1823 : : ut_sequence_step_cb, &completed);
1824 : 3 : CU_ASSERT_EQUAL(rc, 0);
1825 : :
1826 : 3 : ut_seq.complete = false;
1827 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1828 : :
1829 : 3 : poll_threads();
1830 : :
1831 : 3 : CU_ASSERT_EQUAL(completed, 2);
1832 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1833 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1834 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1835 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 1);
1836 : :
1837 : : /* Check copy + encrypt + copy */
1838 : 3 : seq = NULL;
1839 : 3 : completed = 0;
1840 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1841 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
1842 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].dst_iovcnt = 1;
1843 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].src_iovcnt = 1;
1844 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].src_iovs = &exp_iovs[0];
1845 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].dst_iovs = &exp_iovs[1];
1846 : 3 : exp_iovs[0].iov_base = tmp[0];
1847 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1848 : 3 : exp_iovs[1].iov_base = buf;
1849 : 3 : exp_iovs[1].iov_len = sizeof(buf);
1850 : :
1851 : 3 : dst_iovs[0].iov_base = tmp[1];
1852 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1853 : 3 : src_iovs[0].iov_base = tmp[0];
1854 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1855 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1856 : 1 : &src_iovs[0], 1, NULL, NULL,
1857 : : ut_sequence_step_cb, &completed);
1858 : 3 : CU_ASSERT_EQUAL(rc, 0);
1859 : :
1860 : 3 : dst_iovs[1].iov_base = tmp[2];
1861 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
1862 : 3 : src_iovs[1].iov_base = tmp[1];
1863 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1864 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
1865 : 1 : &src_iovs[1], 1, NULL, NULL, 0, sizeof(tmp[2]),
1866 : : ut_sequence_step_cb, &completed);
1867 : 3 : CU_ASSERT_EQUAL(rc, 0);
1868 : :
1869 : 3 : dst_iovs[2].iov_base = buf;
1870 : 3 : dst_iovs[2].iov_len = sizeof(buf);
1871 : 3 : src_iovs[2].iov_base = tmp[2];
1872 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
1873 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
1874 : 1 : &src_iovs[2], 1, NULL, NULL,
1875 : : ut_sequence_step_cb, &completed);
1876 : 3 : CU_ASSERT_EQUAL(rc, 0);
1877 : :
1878 : 3 : ut_seq.complete = false;
1879 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1880 : :
1881 : 3 : poll_threads();
1882 : :
1883 : 3 : CU_ASSERT_EQUAL(completed, 3);
1884 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1885 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1886 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1887 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
1888 : :
1889 : : /* Check copy + decrypt + copy */
1890 : 3 : seq = NULL;
1891 : 3 : completed = 0;
1892 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1893 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
1894 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovcnt = 1;
1895 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovcnt = 1;
1896 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovs = &exp_iovs[0];
1897 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovs = &exp_iovs[1];
1898 : 3 : exp_iovs[0].iov_base = tmp[0];
1899 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1900 : 3 : exp_iovs[1].iov_base = buf;
1901 : 3 : exp_iovs[1].iov_len = sizeof(buf);
1902 : :
1903 : 3 : dst_iovs[0].iov_base = tmp[1];
1904 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1905 : 3 : src_iovs[0].iov_base = tmp[0];
1906 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1907 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
1908 : 1 : &src_iovs[0], 1, NULL, NULL,
1909 : : ut_sequence_step_cb, &completed);
1910 : 3 : CU_ASSERT_EQUAL(rc, 0);
1911 : :
1912 : 3 : dst_iovs[1].iov_base = tmp[2];
1913 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
1914 : 3 : src_iovs[1].iov_base = tmp[1];
1915 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1916 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
1917 : 1 : &src_iovs[1], 1, NULL, NULL, 0, sizeof(tmp[2]),
1918 : : ut_sequence_step_cb, &completed);
1919 : 3 : CU_ASSERT_EQUAL(rc, 0);
1920 : :
1921 : 3 : dst_iovs[2].iov_base = buf;
1922 : 3 : dst_iovs[2].iov_len = sizeof(buf);
1923 : 3 : src_iovs[2].iov_base = tmp[2];
1924 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
1925 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
1926 : 1 : &src_iovs[2], 1, NULL, NULL,
1927 : : ut_sequence_step_cb, &completed);
1928 : 3 : CU_ASSERT_EQUAL(rc, 0);
1929 : :
1930 : 3 : ut_seq.complete = false;
1931 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1932 : :
1933 : 3 : poll_threads();
1934 : :
1935 : 3 : CU_ASSERT_EQUAL(completed, 3);
1936 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1937 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1938 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1939 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
1940 : :
1941 : : /* Check a sequence with memory domains and verify their pointers (and their contexts) are
1942 : : * correctly set on the next/prev task when a copy is removed */
1943 : 3 : seq = NULL;
1944 : 3 : completed = 0;
1945 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
1946 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
1947 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovcnt = 1;
1948 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovcnt = 1;
1949 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovs = &exp_iovs[0];
1950 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovs = &exp_iovs[1];
1951 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_domain = (void *)0x1;
1952 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_domain_ctx = (void *)0x2;
1953 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_domain = (void *)0x3;
1954 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_domain_ctx = (void *)0x4;
1955 : 3 : exp_iovs[0].iov_base = tmp[0];
1956 : 3 : exp_iovs[0].iov_len = sizeof(tmp[0]);
1957 : 3 : exp_iovs[1].iov_base = buf;
1958 : 3 : exp_iovs[1].iov_len = sizeof(buf);
1959 : :
1960 : 3 : dst_iovs[0].iov_base = tmp[1];
1961 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
1962 : 3 : src_iovs[0].iov_base = tmp[0];
1963 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
1964 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, (void *)0xdead, (void *)0xbeef,
1965 : 1 : &src_iovs[0], 1, (void *)0x3, (void *)0x4,
1966 : : ut_sequence_step_cb, &completed);
1967 : 3 : CU_ASSERT_EQUAL(rc, 0);
1968 : :
1969 : 3 : dst_iovs[1].iov_base = tmp[2];
1970 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
1971 : 3 : src_iovs[1].iov_base = tmp[1];
1972 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
1973 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[1], 1, (void *)0xdead, (void *)0xbeef,
1974 : 1 : &src_iovs[1], 1, (void *)0xdead, (void *)0xbeef, 0,
1975 : : sizeof(tmp[2]), ut_sequence_step_cb, &completed);
1976 : 3 : CU_ASSERT_EQUAL(rc, 0);
1977 : :
1978 : 3 : dst_iovs[2].iov_base = buf;
1979 : 3 : dst_iovs[2].iov_len = sizeof(buf);
1980 : 3 : src_iovs[2].iov_base = tmp[2];
1981 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
1982 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, (void *)0x1, (void *)0x2,
1983 : 1 : &src_iovs[2], 1, (void *)0xdead, (void *)0xbeef,
1984 : : ut_sequence_step_cb, &completed);
1985 : 3 : CU_ASSERT_EQUAL(rc, 0);
1986 : :
1987 : 3 : ut_seq.complete = false;
1988 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
1989 : :
1990 : 3 : poll_threads();
1991 : :
1992 : 3 : CU_ASSERT_EQUAL(completed, 3);
1993 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
1994 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
1995 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
1996 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
1997 : :
1998 : : /* Cleanup module pointers to make subsequent tests work correctly */
1999 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2000 : 51 : g_modules_opc[i] = modules[i];
2001 : 17 : }
2002 : :
2003 : 3 : g_module.supports_memory_domains = false;
2004 : 3 : ut_clear_operations();
2005 : 3 : spdk_put_io_channel(ioch);
2006 : 3 : poll_threads();
2007 : 3 : }
2008 : :
2009 : : static int
2010 : 54 : ut_submit_decompress(struct spdk_io_channel *ch, struct spdk_accel_task *task)
2011 : : {
2012 : 54 : spdk_iovmove(task->s.iovs, task->s.iovcnt, task->d.iovs, task->d.iovcnt);
2013 : :
2014 : 54 : spdk_accel_task_complete(task, 0);
2015 : :
2016 : 54 : return 0;
2017 : : }
2018 : :
2019 : : static void
2020 : 3 : test_sequence_accel_buffers(void)
2021 : : {
2022 : 3 : struct spdk_accel_sequence *seq = NULL;
2023 : : struct spdk_io_channel *ioch;
2024 : : struct accel_io_channel *accel_ch;
2025 : 2 : struct ut_sequence ut_seq;
2026 : 2 : struct iovec src_iovs[3], dst_iovs[3];
2027 : 2 : char srcbuf[4096], dstbuf[4096], expected[4096];
2028 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
2029 : 2 : void *buf[2], *domain_ctx[2], *iobuf_buf;
2030 : 2 : struct spdk_memory_domain *domain[2];
2031 : : struct spdk_iobuf_buffer *cache_entry;
2032 : : struct spdk_iobuf_pool_cache *small;
2033 : 2 : spdk_iobuf_buffer_stailq_t small_cache;
2034 : : uint32_t small_cache_count;
2035 : 2 : int i, rc, completed;
2036 : 3 : struct spdk_iobuf_opts opts_iobuf = {};
2037 : :
2038 : : /* Set up the iobuf to always use the "small" pool */
2039 : 3 : opts_iobuf.large_bufsize = 0x20000;
2040 : 3 : opts_iobuf.large_pool_count = 0;
2041 : 3 : opts_iobuf.small_bufsize = 0x10000;
2042 : 3 : opts_iobuf.small_pool_count = 32;
2043 : :
2044 : 3 : rc = spdk_iobuf_set_opts(&opts_iobuf);
2045 : 3 : CU_ASSERT(rc == 0);
2046 : :
2047 : 3 : ioch = spdk_accel_get_io_channel();
2048 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
2049 : :
2050 : : /* Override the submit_tasks function */
2051 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
2052 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2053 : 51 : modules[i] = g_modules_opc[i];
2054 : 51 : g_modules_opc[i] = g_module;
2055 : 17 : }
2056 : : /* Intercept decompress to make it simply copy the data, so that we can chain multiple
2057 : : * decompress operations together in one sequence.
2058 : : */
2059 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].submit = ut_submit_decompress;
2060 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].submit = sw_accel_submit_tasks;
2061 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].submit = sw_accel_submit_tasks;
2062 : :
2063 : : /* Check the simplest case: one operation using accel buffer as destination + copy operation
2064 : : * specifying the actual destination buffer
2065 : : */
2066 : 3 : memset(srcbuf, 0xa5, 4096);
2067 : 3 : memset(dstbuf, 0x0, 4096);
2068 : 3 : memset(expected, 0xa5, 4096);
2069 : 3 : completed = 0;
2070 : 3 : seq = NULL;
2071 : :
2072 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2073 : 3 : CU_ASSERT_EQUAL(rc, 0);
2074 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2075 : :
2076 : 3 : src_iovs[0].iov_base = srcbuf;
2077 : 3 : src_iovs[0].iov_len = 4096;
2078 : 3 : dst_iovs[0].iov_base = buf[0];
2079 : 3 : dst_iovs[0].iov_len = 4096;
2080 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, domain[0], domain_ctx[0],
2081 : 1 : &src_iovs[0], 1, NULL, NULL,
2082 : : ut_sequence_step_cb, &completed);
2083 : 3 : CU_ASSERT_EQUAL(rc, 0);
2084 : :
2085 : 3 : src_iovs[1].iov_base = buf[0];
2086 : 3 : src_iovs[1].iov_len = 4096;
2087 : 3 : dst_iovs[1].iov_base = dstbuf;
2088 : 3 : dst_iovs[1].iov_len = 4096;
2089 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
2090 : 1 : &src_iovs[1], 1, domain[0], domain_ctx[0],
2091 : : ut_sequence_step_cb, &completed);
2092 : 3 : CU_ASSERT_EQUAL(rc, 0);
2093 : :
2094 : 3 : ut_seq.complete = false;
2095 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2096 : :
2097 : 3 : poll_threads();
2098 : :
2099 : 3 : CU_ASSERT_EQUAL(completed, 2);
2100 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2101 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2102 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2103 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2104 : :
2105 : : /* Start with a fill operation using accel buffer, followed by a decompress using another
2106 : : * accel buffer as dst, followed by a copy operation specifying dst buffer of the whole
2107 : : * sequence
2108 : : */
2109 : 3 : memset(srcbuf, 0x0, 4096);
2110 : 3 : memset(dstbuf, 0x0, 4096);
2111 : 3 : memset(expected, 0x5a, 4096);
2112 : 3 : completed = 0;
2113 : 3 : seq = NULL;
2114 : :
2115 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2116 : 3 : CU_ASSERT_EQUAL(rc, 0);
2117 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2118 : :
2119 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 4096, domain[0], domain_ctx[0], 0x5a,
2120 : : ut_sequence_step_cb, &completed);
2121 : 3 : CU_ASSERT_EQUAL(rc, 0);
2122 : :
2123 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[1], &domain[1], &domain_ctx[1]);
2124 : 3 : CU_ASSERT_EQUAL(rc, 0);
2125 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[1]);
2126 : :
2127 : 3 : src_iovs[0].iov_base = buf[0];
2128 : 3 : src_iovs[0].iov_len = 4096;
2129 : 3 : dst_iovs[0].iov_base = buf[1];
2130 : 3 : dst_iovs[0].iov_len = 4096;
2131 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, domain[1], domain_ctx[1],
2132 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2133 : : ut_sequence_step_cb, &completed);
2134 : 3 : CU_ASSERT_EQUAL(rc, 0);
2135 : :
2136 : 3 : src_iovs[1].iov_base = buf[1];
2137 : 3 : src_iovs[1].iov_len = 4096;
2138 : 3 : dst_iovs[1].iov_base = dstbuf;
2139 : 3 : dst_iovs[1].iov_len = 4096;
2140 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
2141 : 1 : &src_iovs[1], 1, domain[1], domain_ctx[1],
2142 : : ut_sequence_step_cb, &completed);
2143 : :
2144 : 3 : ut_seq.complete = false;
2145 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2146 : :
2147 : 3 : poll_threads();
2148 : :
2149 : 3 : CU_ASSERT_EQUAL(completed, 3);
2150 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2151 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2152 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2153 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2154 : 3 : spdk_accel_put_buf(ioch, buf[1], domain[1], domain_ctx[1]);
2155 : :
2156 : : /* Check the same, but with two decompress operations with the first one being in-place */
2157 : 3 : memset(srcbuf, 0x0, 4096);
2158 : 3 : memset(dstbuf, 0x0, 4096);
2159 : 3 : memset(expected, 0x5a, 4096);
2160 : 3 : completed = 0;
2161 : 3 : seq = NULL;
2162 : :
2163 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2164 : 3 : CU_ASSERT_EQUAL(rc, 0);
2165 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2166 : :
2167 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 4096, domain[0], domain_ctx[0], 0x5a,
2168 : : ut_sequence_step_cb, &completed);
2169 : 3 : CU_ASSERT_EQUAL(rc, 0);
2170 : :
2171 : 3 : src_iovs[0].iov_base = buf[0];
2172 : 3 : src_iovs[0].iov_len = 4096;
2173 : 3 : dst_iovs[0].iov_base = buf[0];
2174 : 3 : dst_iovs[0].iov_len = 4096;
2175 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, domain[0], domain_ctx[0],
2176 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2177 : : ut_sequence_step_cb, &completed);
2178 : 3 : CU_ASSERT_EQUAL(rc, 0);
2179 : :
2180 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[1], &domain[1], &domain_ctx[1]);
2181 : 3 : CU_ASSERT_EQUAL(rc, 0);
2182 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[1]);
2183 : :
2184 : 3 : src_iovs[1].iov_base = buf[0];
2185 : 3 : src_iovs[1].iov_len = 4096;
2186 : 3 : dst_iovs[1].iov_base = buf[1];
2187 : 3 : dst_iovs[1].iov_len = 4096;
2188 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, domain[1], domain_ctx[1],
2189 : 1 : &src_iovs[1], 1, domain[0], domain_ctx[0],
2190 : : ut_sequence_step_cb, &completed);
2191 : 3 : CU_ASSERT_EQUAL(rc, 0);
2192 : :
2193 : 3 : src_iovs[2].iov_base = buf[1];
2194 : 3 : src_iovs[2].iov_len = 4096;
2195 : 3 : dst_iovs[2].iov_base = dstbuf;
2196 : 3 : dst_iovs[2].iov_len = 4096;
2197 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
2198 : 1 : &src_iovs[2], 1, domain[1], domain_ctx[1],
2199 : : ut_sequence_step_cb, &completed);
2200 : :
2201 : 3 : ut_seq.complete = false;
2202 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2203 : :
2204 : 3 : poll_threads();
2205 : :
2206 : 3 : CU_ASSERT_EQUAL(completed, 4);
2207 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2208 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2209 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2210 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2211 : 3 : spdk_accel_put_buf(ioch, buf[1], domain[1], domain_ctx[1]);
2212 : :
2213 : : /* Check that specifying offsets within accel buffers works correctly */
2214 : 3 : memset(srcbuf, 0x0, 4096);
2215 : 3 : memset(dstbuf, 0x0, 4096);
2216 : 3 : completed = 0;
2217 : 3 : seq = NULL;
2218 : :
2219 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2220 : 3 : CU_ASSERT_EQUAL(rc, 0);
2221 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2222 : :
2223 : : /* Fill in each 1K of the buffer with different pattern */
2224 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 1024, domain[0], domain_ctx[0], 0xa5,
2225 : : ut_sequence_step_cb, &completed);
2226 : 3 : CU_ASSERT_EQUAL(rc, 0);
2227 : :
2228 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 1024, 1024, domain[0], domain_ctx[0],
2229 : : 0x5a, ut_sequence_step_cb, &completed);
2230 : 3 : CU_ASSERT_EQUAL(rc, 0);
2231 : :
2232 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 2048, 1024, domain[0], domain_ctx[0],
2233 : : 0xfe, ut_sequence_step_cb, &completed);
2234 : 3 : CU_ASSERT_EQUAL(rc, 0);
2235 : :
2236 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 3072, 1024, domain[0], domain_ctx[0],
2237 : : 0xed, ut_sequence_step_cb, &completed);
2238 : 3 : CU_ASSERT_EQUAL(rc, 0);
2239 : :
2240 : 3 : src_iovs[0].iov_base = buf[0];
2241 : 3 : src_iovs[0].iov_len = 4096;
2242 : 3 : dst_iovs[0].iov_base = dstbuf;
2243 : 3 : dst_iovs[0].iov_len = 4096;
2244 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
2245 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2246 : : ut_sequence_step_cb, &completed);
2247 : :
2248 : 3 : ut_seq.complete = false;
2249 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2250 : :
2251 : 3 : poll_threads();
2252 : :
2253 : 3 : memset(&expected[0], 0xa5, 1024);
2254 : 3 : memset(&expected[1024], 0x5a, 1024);
2255 : 3 : memset(&expected[2048], 0xfe, 1024);
2256 : 3 : memset(&expected[3072], 0xed, 1024);
2257 : 3 : CU_ASSERT_EQUAL(completed, 5);
2258 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2259 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2260 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2261 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2262 : :
2263 : : /* Check the same but this time with a decompress operation on part of the buffer (512B
2264 : : * offset) */
2265 : 3 : memset(srcbuf, 0x0, 4096);
2266 : 3 : memset(dstbuf, 0x0, 4096);
2267 : 3 : completed = 0;
2268 : 3 : seq = NULL;
2269 : :
2270 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2271 : 3 : CU_ASSERT_EQUAL(rc, 0);
2272 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2273 : :
2274 : : /* Fill in each 1K of the buffer with different pattern */
2275 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 1024, domain[0], domain_ctx[0], 0xa5,
2276 : : ut_sequence_step_cb, &completed);
2277 : 3 : CU_ASSERT_EQUAL(rc, 0);
2278 : :
2279 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 1024, 1024, domain[0], domain_ctx[0],
2280 : : 0x5a, ut_sequence_step_cb, &completed);
2281 : 3 : CU_ASSERT_EQUAL(rc, 0);
2282 : :
2283 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 2048, 1024, domain[0], domain_ctx[0],
2284 : : 0xfe, ut_sequence_step_cb, &completed);
2285 : 3 : CU_ASSERT_EQUAL(rc, 0);
2286 : :
2287 : 3 : rc = spdk_accel_append_fill(&seq, ioch, (char *)buf[0] + 3072, 1024, domain[0], domain_ctx[0],
2288 : : 0xed, ut_sequence_step_cb, &completed);
2289 : 3 : CU_ASSERT_EQUAL(rc, 0);
2290 : :
2291 : 3 : rc = spdk_accel_get_buf(ioch, 3072, &buf[1], &domain[1], &domain_ctx[1]);
2292 : 3 : CU_ASSERT_EQUAL(rc, 0);
2293 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[1]);
2294 : :
2295 : 3 : src_iovs[0].iov_base = (char *)buf[0] + 512;
2296 : 3 : src_iovs[0].iov_len = 3072;
2297 : 3 : dst_iovs[0].iov_base = (char *)buf[1] + 256;
2298 : 3 : dst_iovs[0].iov_len = 3072;
2299 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, domain[1], domain_ctx[1],
2300 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2301 : : ut_sequence_step_cb, &completed);
2302 : :
2303 : 3 : src_iovs[1].iov_base = (char *)buf[1] + 256;
2304 : 3 : src_iovs[1].iov_len = 3072;
2305 : 3 : dst_iovs[1].iov_base = dstbuf;
2306 : 3 : dst_iovs[1].iov_len = 3072;
2307 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
2308 : 1 : &src_iovs[1], 1, domain[1], domain_ctx[1],
2309 : : ut_sequence_step_cb, &completed);
2310 : :
2311 : 3 : ut_seq.complete = false;
2312 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2313 : :
2314 : 3 : poll_threads();
2315 : :
2316 : 3 : memset(&expected[0], 0xa5, 512);
2317 : 3 : memset(&expected[512], 0x5a, 1024);
2318 : 3 : memset(&expected[1536], 0xfe, 1024);
2319 : 3 : memset(&expected[2560], 0xed, 512);
2320 : 3 : CU_ASSERT_EQUAL(completed, 6);
2321 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2322 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2323 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 3072), 0);
2324 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2325 : 3 : spdk_accel_put_buf(ioch, buf[1], domain[1], domain_ctx[1]);
2326 : :
2327 : : /* Check that if iobuf pool is empty, the sequence processing will wait until a buffer is
2328 : : * available
2329 : : */
2330 : 3 : accel_ch = spdk_io_channel_get_ctx(ioch);
2331 : 3 : small = &accel_ch->iobuf.cache[0].small;
2332 : 3 : small_cache_count = small->cache_count;
2333 : 3 : STAILQ_INIT(&small_cache);
2334 [ + + + + ]: 3 : STAILQ_SWAP(&small->cache, &small_cache, spdk_iobuf_buffer);
2335 : 3 : small->cache_count = 0;
2336 : 3 : small->cache_size = 0;
2337 : 3 : g_iobuf.small_pool_count = 0;
2338 : :
2339 : : /* First allocate a single buffer used by two operations */
2340 : 3 : memset(srcbuf, 0x0, 4096);
2341 : 3 : memset(dstbuf, 0x0, 4096);
2342 : 3 : memset(expected, 0xa5, 4096);
2343 : 3 : completed = 0;
2344 : 3 : seq = NULL;
2345 : :
2346 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2347 : 3 : CU_ASSERT_EQUAL(rc, 0);
2348 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2349 : :
2350 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 4096, domain[0], domain_ctx[0], 0xa5,
2351 : : ut_sequence_step_cb, &completed);
2352 : 3 : CU_ASSERT_EQUAL(rc, 0);
2353 : :
2354 : 3 : src_iovs[0].iov_base = buf[0];
2355 : 3 : src_iovs[0].iov_len = 4096;
2356 : 3 : dst_iovs[0].iov_base = dstbuf;
2357 : 3 : dst_iovs[0].iov_len = 4096;
2358 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
2359 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2360 : : ut_sequence_step_cb, &completed);
2361 : :
2362 : 3 : ut_seq.complete = false;
2363 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2364 : :
2365 : 3 : poll_threads();
2366 : :
2367 : 3 : CU_ASSERT_EQUAL(completed, 0);
2368 [ - + ]: 3 : CU_ASSERT(!ut_seq.complete);
2369 : :
2370 : : /* Get a buffer and return it to the pool to trigger the sequence to finish */
2371 : 3 : g_iobuf.small_pool_count = 1;
2372 : 3 : iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
2373 : 3 : CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
2374 : 3 : CU_ASSERT(g_iobuf.small_pool_count == 0);
2375 : 3 : spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);
2376 : :
2377 : 3 : poll_threads();
2378 : :
2379 : 3 : CU_ASSERT_EQUAL(completed, 2);
2380 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2381 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2382 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2383 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2384 : :
2385 : : /* Return the buffers back to the cache */
2386 [ - + ]: 3 : while (!STAILQ_EMPTY(&small->cache)) {
2387 : 0 : cache_entry = STAILQ_FIRST(&small->cache);
2388 [ # # ]: 0 : STAILQ_REMOVE_HEAD(&small->cache, stailq);
2389 [ # # ]: 0 : STAILQ_INSERT_HEAD(&small_cache, cache_entry, stailq);
2390 : 0 : small_cache_count++;
2391 : : }
2392 : 3 : small->cache_count = 0;
2393 : 3 : g_iobuf.small_pool_count = 0;
2394 : :
2395 : : /* Check a bit more complex scenario, with two buffers in the sequence */
2396 : 3 : memset(srcbuf, 0x0, 4096);
2397 : 3 : memset(dstbuf, 0x0, 4096);
2398 : 3 : memset(expected, 0x5a, 4096);
2399 : 3 : completed = 0;
2400 : 3 : seq = NULL;
2401 : :
2402 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[0], &domain[0], &domain_ctx[0]);
2403 : 3 : CU_ASSERT_EQUAL(rc, 0);
2404 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[0]);
2405 : :
2406 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf[0], 4096, domain[0], domain_ctx[0], 0x5a,
2407 : : ut_sequence_step_cb, &completed);
2408 : 3 : CU_ASSERT_EQUAL(rc, 0);
2409 : :
2410 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf[1], &domain[1], &domain_ctx[1]);
2411 : 3 : CU_ASSERT_EQUAL(rc, 0);
2412 : 3 : CU_ASSERT_PTR_NOT_NULL(buf[1]);
2413 : :
2414 : 3 : src_iovs[0].iov_base = buf[0];
2415 : 3 : src_iovs[0].iov_len = 4096;
2416 : 3 : dst_iovs[0].iov_base = buf[1];
2417 : 3 : dst_iovs[0].iov_len = 4096;
2418 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, domain[1], domain_ctx[1],
2419 : 1 : &src_iovs[0], 1, domain[0], domain_ctx[0],
2420 : : ut_sequence_step_cb, &completed);
2421 : 3 : CU_ASSERT_EQUAL(rc, 0);
2422 : :
2423 : 3 : src_iovs[1].iov_base = buf[1];
2424 : 3 : src_iovs[1].iov_len = 4096;
2425 : 3 : dst_iovs[1].iov_base = dstbuf;
2426 : 3 : dst_iovs[1].iov_len = 4096;
2427 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
2428 : 1 : &src_iovs[1], 1, domain[1], domain_ctx[1],
2429 : : ut_sequence_step_cb, &completed);
2430 : 3 : CU_ASSERT_EQUAL(rc, 0);
2431 : :
2432 : 3 : ut_seq.complete = false;
2433 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2434 : :
2435 : 3 : poll_threads();
2436 : :
2437 : 3 : CU_ASSERT_EQUAL(completed, 0);
2438 [ - + ]: 3 : CU_ASSERT(!ut_seq.complete);
2439 : :
2440 : 3 : g_iobuf.small_pool_count = 1;
2441 : 3 : iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
2442 : 3 : CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
2443 : 3 : g_iobuf.small_pool_count = 0;
2444 : 3 : spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);
2445 : :
2446 : : /* One buffer is not enough to finish the whole sequence */
2447 : 3 : poll_threads();
2448 [ - + ]: 3 : CU_ASSERT(!ut_seq.complete);
2449 : :
2450 : 3 : g_iobuf.small_pool_count = 1;
2451 : 3 : iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, 4096, NULL, NULL);
2452 : 3 : CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
2453 : 3 : g_iobuf.small_pool_count = 0;
2454 : 3 : spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, 4096);
2455 : :
2456 : 3 : poll_threads();
2457 : :
2458 : 3 : CU_ASSERT_EQUAL(completed, 3);
2459 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2460 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2461 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2462 : 3 : spdk_accel_put_buf(ioch, buf[0], domain[0], domain_ctx[0]);
2463 : 3 : spdk_accel_put_buf(ioch, buf[1], domain[1], domain_ctx[1]);
2464 : :
2465 : : /* Return the buffers back to the cache */
2466 [ - + ]: 3 : while (!STAILQ_EMPTY(&small->cache)) {
2467 : 0 : cache_entry = STAILQ_FIRST(&small->cache);
2468 [ # # ]: 0 : STAILQ_REMOVE_HEAD(&small->cache, stailq);
2469 [ # # ]: 0 : STAILQ_INSERT_HEAD(&small_cache, cache_entry, stailq);
2470 : 0 : small_cache_count++;
2471 : : }
2472 : 3 : small->cache_count = 0;
2473 : :
2474 : 3 : g_iobuf.small_pool_count = 32;
2475 [ + + + + ]: 3 : STAILQ_SWAP(&small->cache, &small_cache, spdk_iobuf_buffer);
2476 : 3 : small->cache_count = small_cache_count;
2477 : :
2478 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2479 : 51 : g_modules_opc[i] = modules[i];
2480 : 17 : }
2481 : :
2482 : 3 : ut_clear_operations();
2483 : 3 : spdk_put_io_channel(ioch);
2484 : 3 : poll_threads();
2485 : 3 : }
2486 : :
2487 : : static void
2488 : 72 : ut_domain_ctx_init(struct ut_domain_ctx *ctx, void *base, size_t len, struct iovec *expected)
2489 : : {
2490 : 72 : ctx->iov.iov_base = base;
2491 : 72 : ctx->iov.iov_len = len;
2492 : 72 : ctx->expected = *expected;
2493 : 72 : ctx->pull_submit_status = 0;
2494 : 72 : ctx->push_submit_status = 0;
2495 : 72 : ctx->pull_complete_status = 0;
2496 : 72 : ctx->push_complete_status = 0;
2497 : 72 : }
2498 : :
2499 : : static void
2500 : 3 : test_sequence_memory_domain(void)
2501 : : {
2502 : 3 : struct spdk_accel_sequence *seq = NULL;
2503 : : struct spdk_io_channel *ioch;
2504 : : struct accel_io_channel *accel_ch;
2505 : 2 : struct ut_sequence ut_seq;
2506 : 2 : struct ut_domain_ctx domctx[4];
2507 : : struct spdk_iobuf_buffer *cache_entry;
2508 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
2509 : 2 : struct spdk_memory_domain *accel_domain;
2510 : : struct spdk_iobuf_pool_cache *small;
2511 : 2 : spdk_iobuf_buffer_stailq_t small_cache;
2512 : 2 : char srcbuf[4096], dstbuf[4096], expected[4096], tmp[4096];
2513 : 2 : struct iovec src_iovs[2], dst_iovs[2];
2514 : : uint32_t small_cache_count;
2515 : 2 : void *accel_buf, *accel_domain_ctx, *iobuf_buf;
2516 : 2 : int i, rc, completed;
2517 : :
2518 : 3 : ioch = spdk_accel_get_io_channel();
2519 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
2520 : :
2521 : : /* Override the submit_tasks function */
2522 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
2523 : 3 : g_module.supports_memory_domains = false;
2524 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2525 : 51 : modules[i] = g_modules_opc[i];
2526 : 51 : g_modules_opc[i] = g_module;
2527 : 17 : }
2528 : : /* Intercept decompress to make it simply copy the data, so that we can chain multiple
2529 : : * decompress operations together in one sequence.
2530 : : */
2531 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].submit = ut_submit_decompress;
2532 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].submit = sw_accel_submit_tasks;
2533 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].submit = sw_accel_submit_tasks;
2534 : :
2535 : : /* First check the simplest case - single fill operation with dstbuf in domain */
2536 : 3 : memset(expected, 0xa5, sizeof(expected));
2537 : 3 : memset(dstbuf, 0x0, sizeof(dstbuf));
2538 : 3 : completed = 0;
2539 : 3 : seq = NULL;
2540 : :
2541 : : /* Use some garbage pointer as dst and use domain ctx to get the actual dstbuf */
2542 : 3 : dst_iovs[0].iov_base = (void *)0xcafebabe;
2543 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2544 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2545 : :
2546 : 4 : rc = spdk_accel_append_fill(&seq, ioch, dst_iovs[0].iov_base, dst_iovs[0].iov_len,
2547 : 1 : g_ut_domain, &domctx[0], 0xa5,
2548 : : ut_sequence_step_cb, &completed);
2549 : 3 : CU_ASSERT_EQUAL(rc, 0);
2550 : :
2551 : 3 : ut_seq.complete = false;
2552 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2553 : :
2554 : 3 : poll_threads();
2555 : 3 : CU_ASSERT_EQUAL(completed, 1);
2556 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2557 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2558 : 3 : CU_ASSERT_EQUAL(memcmp(expected, dstbuf, sizeof(dstbuf)), 0);
2559 : :
2560 : : /* Check operation with both srcbuf and dstbuf in remote memory domain */
2561 : 3 : memset(expected, 0x5a, sizeof(expected));
2562 : 3 : memset(dstbuf, 0x0, sizeof(dstbuf));
2563 : 3 : memset(srcbuf, 0x5a, sizeof(dstbuf));
2564 : 3 : completed = 0;
2565 : 3 : seq = NULL;
2566 : :
2567 : 3 : src_iovs[0].iov_base = (void *)0xcafebabe;
2568 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2569 : 3 : dst_iovs[0].iov_base = (void *)0xbeefdead;
2570 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2571 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2572 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2573 : :
2574 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2575 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2576 : : ut_sequence_step_cb, &completed);
2577 : 3 : CU_ASSERT_EQUAL(rc, 0);
2578 : :
2579 : 3 : ut_seq.complete = false;
2580 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2581 : :
2582 : 3 : poll_threads();
2583 : 3 : CU_ASSERT_EQUAL(completed, 1);
2584 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2585 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2586 : 3 : CU_ASSERT_EQUAL(memcmp(expected, dstbuf, sizeof(dstbuf)), 0);
2587 : :
2588 : : /* Two operations using a buffer in remote domain */
2589 : 3 : memset(expected, 0xa5, sizeof(expected));
2590 : 3 : memset(srcbuf, 0xa5, sizeof(srcbuf));
2591 : 3 : memset(tmp, 0x0, sizeof(tmp));
2592 : 3 : memset(dstbuf, 0x0, sizeof(dstbuf));
2593 : 3 : completed = 0;
2594 : 3 : seq = NULL;
2595 : :
2596 : 3 : src_iovs[0].iov_base = (void *)0xcafebabe;
2597 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2598 : 3 : dst_iovs[0].iov_base = (void *)0xbeefdead;
2599 : 3 : dst_iovs[0].iov_len = sizeof(tmp);
2600 : 3 : ut_domain_ctx_init(&domctx[0], tmp, sizeof(tmp), &dst_iovs[0]);
2601 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2602 : :
2603 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2604 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2605 : : ut_sequence_step_cb, &completed);
2606 : 3 : CU_ASSERT_EQUAL(rc, 0);
2607 : :
2608 : 3 : src_iovs[1].iov_base = (void *)0xbeefdead;
2609 : 3 : src_iovs[1].iov_len = sizeof(tmp);
2610 : 3 : dst_iovs[1].iov_base = (void *)0xa5a5a5a5;
2611 : 3 : dst_iovs[1].iov_len = sizeof(dstbuf);
2612 : 3 : ut_domain_ctx_init(&domctx[2], dstbuf, sizeof(dstbuf), &dst_iovs[1]);
2613 : 3 : ut_domain_ctx_init(&domctx[3], tmp, sizeof(tmp), &src_iovs[1]);
2614 : :
2615 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, g_ut_domain, &domctx[2],
2616 : 1 : &src_iovs[1], 1, g_ut_domain, &domctx[3],
2617 : : ut_sequence_step_cb, &completed);
2618 : 3 : CU_ASSERT_EQUAL(rc, 0);
2619 : :
2620 : 3 : ut_seq.complete = false;
2621 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2622 : :
2623 : 3 : poll_threads();
2624 : 3 : CU_ASSERT_EQUAL(completed, 2);
2625 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2626 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2627 : 3 : CU_ASSERT_EQUAL(memcmp(expected, dstbuf, sizeof(dstbuf)), 0);
2628 : :
2629 : : /* Use buffer in remote memory domain and accel buffer at the same time */
2630 : 3 : memset(expected, 0x5a, sizeof(expected));
2631 : 3 : memset(srcbuf, 0x5a, sizeof(expected));
2632 : 3 : memset(dstbuf, 0x0, sizeof(dstbuf));
2633 : 3 : completed = 0;
2634 : 3 : seq = NULL;
2635 : :
2636 : 3 : rc = spdk_accel_get_buf(ioch, sizeof(dstbuf), &accel_buf, &accel_domain, &accel_domain_ctx);
2637 : 3 : CU_ASSERT_EQUAL(rc, 0);
2638 : :
2639 : 3 : src_iovs[0].iov_base = (void *)0xfeedbeef;
2640 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2641 : 3 : dst_iovs[0].iov_base = accel_buf;
2642 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2643 : 3 : ut_domain_ctx_init(&domctx[0], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2644 : :
2645 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, accel_domain, accel_domain_ctx,
2646 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[0],
2647 : : ut_sequence_step_cb, &completed);
2648 : 3 : CU_ASSERT_EQUAL(rc, 0);
2649 : :
2650 : 3 : src_iovs[1].iov_base = accel_buf;
2651 : 3 : src_iovs[1].iov_len = sizeof(dstbuf);
2652 : 3 : dst_iovs[1].iov_base = (void *)0xbeeffeed;
2653 : 3 : dst_iovs[1].iov_len = sizeof(dstbuf);
2654 : 3 : ut_domain_ctx_init(&domctx[1], dstbuf, sizeof(dstbuf), &dst_iovs[1]);
2655 : :
2656 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, g_ut_domain, &domctx[1],
2657 : 1 : &src_iovs[1], 1, accel_domain, accel_domain_ctx,
2658 : : ut_sequence_step_cb, &completed);
2659 : 3 : CU_ASSERT_EQUAL(rc, 0);
2660 : :
2661 : 3 : ut_seq.complete = false;
2662 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2663 : :
2664 : 3 : poll_threads();
2665 : 3 : CU_ASSERT_EQUAL(completed, 2);
2666 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2667 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2668 : 3 : CU_ASSERT_EQUAL(memcmp(expected, dstbuf, sizeof(dstbuf)), 0);
2669 : 3 : spdk_accel_put_buf(ioch, accel_buf, accel_domain, accel_domain_ctx);
2670 : :
2671 : : /* Check that a sequence with memory domains is correctly executed if buffers are not
2672 : : * immediately available */
2673 : 3 : memset(expected, 0xa5, sizeof(expected));
2674 : 3 : memset(srcbuf, 0xa5, sizeof(srcbuf));
2675 : 3 : memset(dstbuf, 0x0, sizeof(dstbuf));
2676 : 3 : completed = 0;
2677 : 3 : seq = NULL;
2678 : : /* Make sure the buffer pool is empty */
2679 : 3 : accel_ch = spdk_io_channel_get_ctx(ioch);
2680 : 3 : small = &accel_ch->iobuf.cache[0].small;
2681 : 3 : small_cache_count = small->cache_count;
2682 : 3 : STAILQ_INIT(&small_cache);
2683 [ + + + + ]: 3 : STAILQ_SWAP(&small->cache, &small_cache, spdk_iobuf_buffer);
2684 : 3 : small->cache_count = 0;
2685 : 3 : g_iobuf.small_pool_count = 0;
2686 : :
2687 : 3 : src_iovs[0].iov_base = (void *)0xdeadbeef;
2688 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2689 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2690 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2691 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2692 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2693 : :
2694 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2695 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2696 : : ut_sequence_step_cb, &completed);
2697 : 3 : CU_ASSERT_EQUAL(rc, 0);
2698 : :
2699 : 3 : ut_seq.complete = false;
2700 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2701 : :
2702 : 3 : poll_threads();
2703 : 3 : CU_ASSERT_EQUAL(completed, 0);
2704 [ - + ]: 3 : CU_ASSERT(!ut_seq.complete);
2705 : :
2706 : : /* Get a buffer and return it to the pool to trigger the sequence to resume. It shouldn't
2707 : : * be able to complete, as it needs two buffers */
2708 : 3 : g_iobuf.small_pool_count = 1;
2709 : 3 : iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, sizeof(dstbuf), NULL, NULL);
2710 : 3 : CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
2711 : 3 : g_iobuf.small_pool_count = 0;
2712 : 3 : spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, sizeof(dstbuf));
2713 : :
2714 : 3 : CU_ASSERT_EQUAL(completed, 0);
2715 [ - + ]: 3 : CU_ASSERT(!ut_seq.complete);
2716 : :
2717 : : /* Return another buffer, this time the sequence should finish */
2718 : 3 : g_iobuf.small_pool_count = 1;
2719 : 3 : iobuf_buf = spdk_iobuf_get(&accel_ch->iobuf, sizeof(dstbuf), NULL, NULL);
2720 : 3 : CU_ASSERT_PTR_NOT_NULL(iobuf_buf);
2721 : 3 : g_iobuf.small_pool_count = 0;
2722 : 3 : spdk_iobuf_put(&accel_ch->iobuf, iobuf_buf, sizeof(dstbuf));
2723 : :
2724 : 3 : poll_threads();
2725 : 3 : CU_ASSERT_EQUAL(completed, 1);
2726 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2727 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2728 : 3 : CU_ASSERT_EQUAL(memcmp(expected, dstbuf, sizeof(dstbuf)), 0);
2729 : :
2730 : : /* Return the buffers back to the cache */
2731 [ - + ]: 3 : while (!STAILQ_EMPTY(&small->cache)) {
2732 : 0 : cache_entry = STAILQ_FIRST(&small->cache);
2733 [ # # ]: 0 : STAILQ_REMOVE_HEAD(&small->cache, stailq);
2734 [ # # ]: 0 : STAILQ_INSERT_HEAD(&small_cache, cache_entry, stailq);
2735 : 0 : small_cache_count++;
2736 : : }
2737 : 3 : small->cache_count = 0;
2738 : :
2739 : 3 : g_iobuf.small_pool_count = 32;
2740 [ + + + + ]: 3 : STAILQ_SWAP(&small->cache, &small_cache, spdk_iobuf_buffer);
2741 : 3 : small->cache_count = small_cache_count;
2742 : :
2743 : : /* Check error cases, starting with an error from spdk_memory_domain_pull_data() */
2744 : 3 : completed = 0;
2745 : 3 : seq = NULL;
2746 : :
2747 : 3 : src_iovs[0].iov_base = (void *)0xdeadbeef;
2748 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2749 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2750 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2751 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2752 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2753 : 3 : domctx[1].pull_submit_status = -E2BIG;
2754 : :
2755 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2756 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2757 : : ut_sequence_step_cb, &completed);
2758 : 3 : CU_ASSERT_EQUAL(rc, 0);
2759 : :
2760 : 3 : ut_seq.complete = false;
2761 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2762 : :
2763 : 3 : CU_ASSERT_EQUAL(completed, 1);
2764 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2765 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -E2BIG);
2766 : :
2767 : : /* Check completion error from spdk_memory_domain_pull_data() */
2768 : 3 : completed = 0;
2769 : 3 : seq = NULL;
2770 : :
2771 : 3 : src_iovs[0].iov_base = (void *)0xdeadbeef;
2772 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2773 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2774 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2775 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2776 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2777 : 3 : domctx[1].pull_complete_status = -EACCES;
2778 : :
2779 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2780 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2781 : : ut_sequence_step_cb, &completed);
2782 : 3 : CU_ASSERT_EQUAL(rc, 0);
2783 : :
2784 : 3 : ut_seq.complete = false;
2785 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2786 : :
2787 : 3 : CU_ASSERT_EQUAL(completed, 1);
2788 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2789 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EACCES);
2790 : :
2791 : : /* Check submission error from spdk_memory_domain_push_data() */
2792 : 3 : completed = 0;
2793 : 3 : seq = NULL;
2794 : :
2795 : 3 : src_iovs[0].iov_base = (void *)0xdeadbeef;
2796 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2797 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2798 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2799 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2800 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2801 : 3 : domctx[0].push_submit_status = -EADDRINUSE;
2802 : :
2803 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2804 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2805 : : ut_sequence_step_cb, &completed);
2806 : 3 : CU_ASSERT_EQUAL(rc, 0);
2807 : :
2808 : 3 : ut_seq.complete = false;
2809 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2810 : :
2811 : 3 : CU_ASSERT_EQUAL(completed, 1);
2812 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2813 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EADDRINUSE);
2814 : :
2815 : : /* Check completion error from spdk_memory_domain_push_data() */
2816 : 3 : completed = 0;
2817 : 3 : seq = NULL;
2818 : :
2819 : 3 : src_iovs[0].iov_base = (void *)0xdeadbeef;
2820 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2821 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2822 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2823 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2824 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2825 : 3 : domctx[0].push_complete_status = -EADDRNOTAVAIL;
2826 : :
2827 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2828 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2829 : : ut_sequence_step_cb, &completed);
2830 : 3 : CU_ASSERT_EQUAL(rc, 0);
2831 : :
2832 : 3 : ut_seq.complete = false;
2833 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2834 : :
2835 : 3 : CU_ASSERT_EQUAL(completed, 1);
2836 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2837 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EADDRNOTAVAIL);
2838 : :
2839 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2840 : 51 : g_modules_opc[i] = modules[i];
2841 : 17 : }
2842 : :
2843 : 3 : ut_clear_operations();
2844 : 3 : spdk_put_io_channel(ioch);
2845 : 3 : poll_threads();
2846 : 3 : }
2847 : :
2848 : : static int
2849 : 12 : ut_submit_decompress_memory_domain(struct spdk_io_channel *ch, struct spdk_accel_task *task)
2850 : : {
2851 : : struct ut_domain_ctx *ctx;
2852 : : struct iovec *src_iovs, *dst_iovs;
2853 : : uint32_t src_iovcnt, dst_iovcnt;
2854 : :
2855 : 12 : src_iovs = task->s.iovs;
2856 : 12 : dst_iovs = task->d.iovs;
2857 : 12 : src_iovcnt = task->s.iovcnt;
2858 : 12 : dst_iovcnt = task->d.iovcnt;
2859 : :
2860 [ + + ]: 12 : if (task->src_domain != NULL) {
2861 : 6 : ctx = task->src_domain_ctx;
2862 [ - + - + ]: 6 : CU_ASSERT_EQUAL(memcmp(task->s.iovs, &ctx->expected, sizeof(struct iovec)), 0);
2863 : 6 : src_iovs = &ctx->iov;
2864 : 6 : src_iovcnt = 1;
2865 : 2 : }
2866 : :
2867 [ + + ]: 12 : if (task->dst_domain != NULL) {
2868 : 9 : ctx = task->dst_domain_ctx;
2869 [ - + - + ]: 9 : CU_ASSERT_EQUAL(memcmp(task->d.iovs, &ctx->expected, sizeof(struct iovec)), 0);
2870 : 9 : dst_iovs = &ctx->iov;
2871 : 9 : dst_iovcnt = 1;
2872 : 3 : }
2873 : :
2874 : 12 : spdk_iovcpy(src_iovs, src_iovcnt, dst_iovs, dst_iovcnt);
2875 : 12 : spdk_accel_task_complete(task, 0);
2876 : :
2877 : 12 : return 0;
2878 : : }
2879 : :
2880 : : static void
2881 : 3 : test_sequence_module_memory_domain(void)
2882 : : {
2883 : 3 : struct spdk_accel_sequence *seq = NULL;
2884 : : struct spdk_io_channel *ioch;
2885 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
2886 : 2 : struct spdk_memory_domain *accel_domain;
2887 : 2 : struct ut_sequence ut_seq;
2888 : 2 : struct ut_domain_ctx domctx[2];
2889 : 2 : struct iovec src_iovs[2], dst_iovs[2];
2890 : 2 : void *buf, *accel_domain_ctx;
2891 : 2 : char srcbuf[4096], dstbuf[4096], tmp[4096], expected[4096];
2892 : 2 : int i, rc, completed;
2893 : :
2894 : 3 : ioch = spdk_accel_get_io_channel();
2895 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
2896 : :
2897 : : /* Override the submit_tasks function */
2898 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
2899 : 3 : g_module.supports_memory_domains = true;
2900 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
2901 : 51 : modules[i] = g_modules_opc[i];
2902 : 51 : g_modules_opc[i] = g_module;
2903 : 17 : }
2904 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].submit = ut_submit_decompress_memory_domain;
2905 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].submit = sw_accel_submit_tasks;
2906 : :
2907 : : /* Check a sequence with both buffers in memory domains */
2908 : 3 : memset(srcbuf, 0xa5, sizeof(srcbuf));
2909 : 3 : memset(expected, 0xa5, sizeof(expected));
2910 : 3 : memset(dstbuf, 0, sizeof(dstbuf));
2911 : 3 : seq = NULL;
2912 : 3 : completed = 0;
2913 : :
2914 : 3 : src_iovs[0].iov_base = (void *)0xcafebabe;
2915 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2916 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2917 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2918 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2919 : 3 : ut_domain_ctx_init(&domctx[1], srcbuf, sizeof(srcbuf), &src_iovs[0]);
2920 : :
2921 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2922 : 1 : &src_iovs[0], 1, g_ut_domain, &domctx[1],
2923 : : ut_sequence_step_cb, &completed);
2924 : 3 : CU_ASSERT_EQUAL(rc, 0);
2925 : :
2926 : 3 : ut_seq.complete = false;
2927 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2928 : :
2929 : 3 : poll_threads();
2930 : :
2931 : 3 : CU_ASSERT_EQUAL(completed, 1);
2932 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2933 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2934 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2935 : :
2936 : : /* Check two operations each with a single buffer in memory domain */
2937 : 3 : memset(srcbuf, 0x5a, sizeof(srcbuf));
2938 : 3 : memset(expected, 0x5a, sizeof(expected));
2939 : 3 : memset(dstbuf, 0, sizeof(dstbuf));
2940 : 3 : memset(tmp, 0, sizeof(tmp));
2941 : 3 : seq = NULL;
2942 : 3 : completed = 0;
2943 : :
2944 : 3 : src_iovs[0].iov_base = srcbuf;
2945 : 3 : src_iovs[0].iov_len = sizeof(srcbuf);
2946 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2947 : 3 : dst_iovs[0].iov_len = sizeof(tmp);
2948 : 3 : ut_domain_ctx_init(&domctx[0], tmp, sizeof(tmp), &dst_iovs[0]);
2949 : :
2950 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2951 : 1 : &src_iovs[0], 1, NULL, NULL,
2952 : : ut_sequence_step_cb, &completed);
2953 : 3 : CU_ASSERT_EQUAL(rc, 0);
2954 : :
2955 : 3 : src_iovs[1].iov_base = (void *)0xfeedbeef;
2956 : 3 : src_iovs[1].iov_len = sizeof(tmp);
2957 : 3 : dst_iovs[1].iov_base = dstbuf;
2958 : 3 : dst_iovs[1].iov_len = sizeof(dstbuf);
2959 : 3 : ut_domain_ctx_init(&domctx[1], tmp, sizeof(tmp), &src_iovs[1]);
2960 : :
2961 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
2962 : 1 : &src_iovs[1], 1, g_ut_domain, &domctx[1],
2963 : : ut_sequence_step_cb, &completed);
2964 : 3 : CU_ASSERT_EQUAL(rc, 0);
2965 : :
2966 : 3 : ut_seq.complete = false;
2967 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
2968 : :
2969 : 3 : poll_threads();
2970 : :
2971 : 3 : CU_ASSERT_EQUAL(completed, 2);
2972 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
2973 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
2974 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
2975 : :
2976 : : /* Check a sequence with an accel buffer and a buffer in a regular memory domain */
2977 : 3 : memset(expected, 0xa5, sizeof(expected));
2978 : 3 : memset(dstbuf, 0, sizeof(dstbuf));
2979 : 3 : memset(tmp, 0, sizeof(tmp));
2980 : 3 : seq = NULL;
2981 : 3 : completed = 0;
2982 : :
2983 : 3 : rc = spdk_accel_get_buf(ioch, 4096, &buf, &accel_domain, &accel_domain_ctx);
2984 : 3 : CU_ASSERT_EQUAL(rc, 0);
2985 : :
2986 : 3 : rc = spdk_accel_append_fill(&seq, ioch, buf, 4096, accel_domain, accel_domain_ctx,
2987 : : 0xa5, ut_sequence_step_cb, &completed);
2988 : 3 : CU_ASSERT_EQUAL(rc, 0);
2989 : :
2990 : 3 : src_iovs[0].iov_base = buf;
2991 : 3 : src_iovs[0].iov_len = 4096;
2992 : 3 : dst_iovs[0].iov_base = (void *)0xfeedbeef;
2993 : 3 : dst_iovs[0].iov_len = sizeof(dstbuf);
2994 : 3 : ut_domain_ctx_init(&domctx[0], dstbuf, sizeof(dstbuf), &dst_iovs[0]);
2995 : :
2996 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, g_ut_domain, &domctx[0],
2997 : 1 : &src_iovs[0], 1, accel_domain, accel_domain_ctx,
2998 : : ut_sequence_step_cb, &completed);
2999 : 3 : CU_ASSERT_EQUAL(rc, 0);
3000 : :
3001 : 3 : ut_seq.complete = false;
3002 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3003 : :
3004 : 3 : poll_threads();
3005 : :
3006 : 3 : CU_ASSERT_EQUAL(completed, 2);
3007 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3008 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3009 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf, expected, 4096), 0);
3010 : :
3011 : 3 : spdk_accel_put_buf(ioch, buf, accel_domain, accel_domain_ctx);
3012 : :
3013 : 3 : g_module.supports_memory_domains = false;
3014 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3015 : 51 : g_modules_opc[i] = modules[i];
3016 : 17 : }
3017 : :
3018 : 3 : ut_clear_operations();
3019 : 3 : spdk_put_io_channel(ioch);
3020 : 3 : poll_threads();
3021 : 3 : }
3022 : :
3023 : : #ifdef SPDK_CONFIG_ISAL_CRYPTO
3024 : : static void
3025 : 3 : ut_encrypt_cb(void *cb_arg, int status)
3026 : : {
3027 : 3 : int *completed = cb_arg;
3028 : :
3029 : 3 : CU_ASSERT_EQUAL(status, 0);
3030 : :
3031 : 3 : *completed = 1;
3032 : 3 : }
3033 : :
3034 : : static void
3035 : 3 : test_sequence_crypto(void)
3036 : : {
3037 : 3 : struct spdk_accel_sequence *seq = NULL;
3038 : : struct spdk_io_channel *ioch;
3039 : : struct spdk_accel_crypto_key *key;
3040 : 3 : struct spdk_accel_crypto_key_create_param key_params = {
3041 : : .cipher = "AES_XTS",
3042 : : .hex_key = "00112233445566778899aabbccddeeff",
3043 : : .hex_key2 = "ffeeddccbbaa99887766554433221100",
3044 : : .key_name = "ut_key",
3045 : : };
3046 : 2 : struct ut_sequence ut_seq;
3047 : 3 : unsigned char buf[4096], encrypted[4096] = {}, data[4096], tmp[3][4096];
3048 : 2 : struct iovec src_iovs[4], dst_iovs[4];
3049 : 3 : int rc, completed = 0;
3050 : : size_t i;
3051 : :
3052 : 3 : ioch = spdk_accel_get_io_channel();
3053 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
3054 : :
3055 : 3 : rc = spdk_accel_crypto_key_create(&key_params);
3056 : 3 : CU_ASSERT_EQUAL(rc, 0);
3057 : 3 : key = spdk_accel_crypto_key_get(key_params.key_name);
3058 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(key != NULL);
3059 : :
3060 [ + + ]: 12291 : for (i = 0; i < sizeof(data); ++i) {
3061 : 12288 : data[i] = (uint8_t)i & 0xff;
3062 : 4096 : }
3063 : :
3064 : 3 : dst_iovs[0].iov_base = encrypted;
3065 : 3 : dst_iovs[0].iov_len = sizeof(encrypted);
3066 : 3 : src_iovs[0].iov_base = data;
3067 : 3 : src_iovs[0].iov_len = sizeof(data);
3068 : 3 : rc = spdk_accel_submit_encrypt(ioch, key, &dst_iovs[0], 1, &src_iovs[0], 1, 0, 4096,
3069 : : ut_encrypt_cb, &completed);
3070 : 3 : CU_ASSERT_EQUAL(rc, 0);
3071 : :
3072 [ + + ]: 6 : while (!completed) {
3073 : 3 : poll_threads();
3074 : : }
3075 : :
3076 : : /* Verify that encryption operation in a sequence produces the same result */
3077 : 3 : seq = NULL;
3078 : 3 : completed = 0;
3079 : :
3080 : 3 : dst_iovs[0].iov_base = tmp[0];
3081 : 3 : dst_iovs[0].iov_len = sizeof(tmp[0]);
3082 : 3 : src_iovs[0].iov_base = data;
3083 : 3 : src_iovs[0].iov_len = sizeof(data);
3084 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3085 : 1 : &src_iovs[0], 1, NULL, NULL,
3086 : : ut_sequence_step_cb, &completed);
3087 : 3 : CU_ASSERT_EQUAL(rc, 0);
3088 : :
3089 : 3 : dst_iovs[1].iov_base = tmp[1];
3090 : 3 : dst_iovs[1].iov_len = sizeof(tmp[1]);
3091 : 3 : src_iovs[1].iov_base = tmp[0];
3092 : 3 : src_iovs[1].iov_len = sizeof(tmp[0]);
3093 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, key, &dst_iovs[1], 1, NULL, NULL,
3094 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3095 : : ut_sequence_step_cb, &completed);
3096 : 3 : CU_ASSERT_EQUAL(rc, 0);
3097 : :
3098 : 3 : dst_iovs[2].iov_base = buf;
3099 : 3 : dst_iovs[2].iov_len = sizeof(buf);
3100 : 3 : src_iovs[2].iov_base = tmp[1];
3101 : 3 : src_iovs[2].iov_len = sizeof(tmp[1]);
3102 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
3103 : 1 : &src_iovs[2], 1, NULL, NULL,
3104 : : ut_sequence_step_cb, &completed);
3105 : 3 : CU_ASSERT_EQUAL(rc, 0);
3106 : :
3107 : 3 : ut_seq.complete = false;
3108 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3109 : :
3110 : 3 : poll_threads();
3111 : :
3112 : 3 : CU_ASSERT_EQUAL(completed, 3);
3113 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3114 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3115 : 3 : CU_ASSERT_EQUAL(memcmp(buf, encrypted, sizeof(buf)), 0);
3116 : :
3117 : : /* Check that decryption produces the original buffer */
3118 : 3 : seq = NULL;
3119 : 3 : completed = 0;
3120 : 3 : memset(buf, 0, sizeof(buf));
3121 : :
3122 : 3 : dst_iovs[0].iov_base = tmp[0];
3123 : 3 : dst_iovs[0].iov_len = sizeof(tmp[0]);
3124 : 3 : src_iovs[0].iov_base = encrypted;
3125 : 3 : src_iovs[0].iov_len = sizeof(encrypted);
3126 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3127 : 1 : &src_iovs[0], 1, NULL, NULL,
3128 : : ut_sequence_step_cb, &completed);
3129 : 3 : CU_ASSERT_EQUAL(rc, 0);
3130 : :
3131 : 3 : dst_iovs[1].iov_base = tmp[1];
3132 : 3 : dst_iovs[1].iov_len = sizeof(tmp[1]);
3133 : 3 : src_iovs[1].iov_base = tmp[0];
3134 : 3 : src_iovs[1].iov_len = sizeof(tmp[0]);
3135 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, key, &dst_iovs[1], 1, NULL, NULL,
3136 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3137 : : ut_sequence_step_cb, &completed);
3138 : 3 : CU_ASSERT_EQUAL(rc, 0);
3139 : :
3140 : 3 : dst_iovs[2].iov_base = buf;
3141 : 3 : dst_iovs[2].iov_len = sizeof(buf);
3142 : 3 : src_iovs[2].iov_base = tmp[1];
3143 : 3 : src_iovs[2].iov_len = sizeof(tmp[1]);
3144 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
3145 : 1 : &src_iovs[2], 1, NULL, NULL,
3146 : : ut_sequence_step_cb, &completed);
3147 : 3 : CU_ASSERT_EQUAL(rc, 0);
3148 : :
3149 : 3 : ut_seq.complete = false;
3150 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3151 : :
3152 : 3 : poll_threads();
3153 : :
3154 : 3 : CU_ASSERT_EQUAL(completed, 3);
3155 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3156 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3157 : 3 : CU_ASSERT_EQUAL(memcmp(buf, data, sizeof(buf)), 0);
3158 : :
3159 : : /* Check encrypt + decrypt in a single sequence */
3160 : 3 : seq = NULL;
3161 : 3 : completed = 0;
3162 : 3 : memset(buf, 0, sizeof(buf));
3163 : :
3164 : 3 : dst_iovs[0].iov_base = tmp[0];
3165 : 3 : dst_iovs[0].iov_len = sizeof(tmp[0]);
3166 : 3 : src_iovs[0].iov_base = data;
3167 : 3 : src_iovs[0].iov_len = sizeof(data);
3168 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3169 : 1 : &src_iovs[0], 1, NULL, NULL,
3170 : : ut_sequence_step_cb, &completed);
3171 : 3 : CU_ASSERT_EQUAL(rc, 0);
3172 : :
3173 : 3 : dst_iovs[1].iov_base = tmp[1];
3174 : 3 : dst_iovs[1].iov_len = sizeof(tmp[1]);
3175 : 3 : src_iovs[1].iov_base = tmp[0];
3176 : 3 : src_iovs[1].iov_len = sizeof(tmp[0]);
3177 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, key, &dst_iovs[1], 1, NULL, NULL,
3178 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3179 : : ut_sequence_step_cb, &completed);
3180 : 3 : CU_ASSERT_EQUAL(rc, 0);
3181 : :
3182 : :
3183 : 3 : dst_iovs[2].iov_base = tmp[2];
3184 : 3 : dst_iovs[2].iov_len = sizeof(tmp[2]);
3185 : 3 : src_iovs[2].iov_base = tmp[1];
3186 : 3 : src_iovs[2].iov_len = sizeof(tmp[1]);
3187 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, key, &dst_iovs[2], 1, NULL, NULL,
3188 : 1 : &src_iovs[2], 1, NULL, NULL, 0, 4096,
3189 : : ut_sequence_step_cb, &completed);
3190 : 3 : CU_ASSERT_EQUAL(rc, 0);
3191 : :
3192 : 3 : dst_iovs[3].iov_base = buf;
3193 : 3 : dst_iovs[3].iov_len = sizeof(buf);
3194 : 3 : src_iovs[3].iov_base = tmp[2];
3195 : 3 : src_iovs[3].iov_len = sizeof(tmp[2]);
3196 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[3], 1, NULL, NULL,
3197 : 1 : &src_iovs[3], 1, NULL, NULL,
3198 : : ut_sequence_step_cb, &completed);
3199 : 3 : CU_ASSERT_EQUAL(rc, 0);
3200 : :
3201 : 3 : ut_seq.complete = false;
3202 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3203 : :
3204 : 3 : poll_threads();
3205 : :
3206 : 3 : CU_ASSERT_EQUAL(completed, 4);
3207 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3208 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3209 : 3 : CU_ASSERT_EQUAL(memcmp(buf, data, sizeof(buf)), 0);
3210 : :
3211 : 3 : rc = spdk_accel_crypto_key_destroy(key);
3212 : 3 : CU_ASSERT_EQUAL(rc, 0);
3213 : 3 : spdk_put_io_channel(ioch);
3214 : 3 : poll_threads();
3215 : 3 : }
3216 : : #endif /* SPDK_CONFIG_ISAL_CRYPTO */
3217 : :
3218 : : static int
3219 : 24 : ut_submit_crypto(struct spdk_io_channel *ch, struct spdk_accel_task *task)
3220 : : {
3221 : 24 : spdk_iovmove(task->s.iovs, task->s.iovcnt, task->d.iovs, task->d.iovcnt);
3222 : :
3223 : 24 : spdk_accel_task_complete(task, 0);
3224 : :
3225 : 24 : return 0;
3226 : : }
3227 : :
3228 : : struct ut_driver_operation {
3229 : : int complete_status;
3230 : : int submit_status;
3231 : : int count;
3232 : : bool supported;
3233 : : };
3234 : :
3235 : : static struct ut_driver_operation g_drv_operations[SPDK_ACCEL_OPC_LAST];
3236 : : static bool g_ut_driver_async_continue;
3237 : :
3238 : : static void
3239 : 3 : ut_driver_async_continue(void *arg)
3240 : : {
3241 : 3 : struct spdk_accel_sequence *seq = arg;
3242 : :
3243 : 3 : spdk_accel_sequence_continue(seq);
3244 : 3 : }
3245 : :
3246 : : static int
3247 : 39 : ut_driver_execute_sequence(struct spdk_io_channel *ch, struct spdk_accel_sequence *seq)
3248 : : {
3249 : : struct spdk_accel_task *task;
3250 : : struct ut_driver_operation *drv_ops;
3251 : :
3252 [ + + ]: 72 : while ((task = spdk_accel_sequence_first_task(seq)) != NULL) {
3253 : 63 : drv_ops = &g_drv_operations[task->op_code];
3254 [ + + + + ]: 63 : if (!drv_ops->supported) {
3255 : 24 : break;
3256 : : }
3257 : :
3258 : 39 : drv_ops->count++;
3259 [ + + ]: 39 : if (drv_ops->submit_status != 0) {
3260 : 3 : return drv_ops->submit_status;
3261 : : }
3262 : :
3263 [ + + ]: 36 : if (drv_ops->complete_status != 0) {
3264 : 3 : spdk_accel_task_complete(task, drv_ops->complete_status);
3265 : 3 : break;
3266 : : }
3267 : :
3268 [ + + + ]: 33 : switch (task->op_code) {
3269 : 10 : case SPDK_ACCEL_OPC_DECOMPRESS:
3270 : 15 : spdk_iovmove(task->s.iovs, task->s.iovcnt, task->d.iovs, task->d.iovcnt);
3271 : 15 : break;
3272 : 12 : case SPDK_ACCEL_OPC_FILL:
3273 : 24 : spdk_iov_memset(task->d.iovs, task->d.iovcnt,
3274 : 18 : (int)(task->fill_pattern & 0xff));
3275 : 18 : break;
3276 : 0 : default:
3277 : 0 : CU_ASSERT(0 && "unexpected opcode");
3278 : 0 : break;
3279 : : }
3280 : :
3281 : 33 : spdk_accel_task_complete(task, 0);
3282 : : }
3283 : :
3284 [ + + + + ]: 36 : if (g_ut_driver_async_continue) {
3285 : 3 : spdk_thread_send_msg(spdk_get_thread(), ut_driver_async_continue, seq);
3286 : 1 : } else {
3287 : 33 : spdk_accel_sequence_continue(seq);
3288 : : }
3289 : :
3290 : 36 : return 0;
3291 : 13 : }
3292 : :
3293 : : static struct spdk_io_channel *
3294 : 0 : ut_driver_get_io_channel(void)
3295 : : {
3296 : 0 : return (void *)0xdeadbeef;
3297 : : }
3298 : :
3299 : : static struct spdk_accel_driver g_ut_driver = {
3300 : : .name = "ut",
3301 : : .execute_sequence = ut_driver_execute_sequence,
3302 : : .get_io_channel = ut_driver_get_io_channel,
3303 : : };
3304 : :
3305 : 3 : SPDK_ACCEL_DRIVER_REGISTER(ut, &g_ut_driver);
3306 : :
3307 : : static void
3308 : 3 : test_sequence_driver(void)
3309 : : {
3310 : 3 : struct spdk_accel_sequence *seq = NULL;
3311 : : struct spdk_io_channel *ioch;
3312 : 3 : struct spdk_accel_crypto_key key = {};
3313 : 2 : struct ut_sequence ut_seq;
3314 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
3315 : 2 : char buf[4096], tmp[3][4096], expected[4096];
3316 : 2 : struct iovec src_iovs[3], dst_iovs[3];
3317 : 3 : int i, rc, completed = 0;
3318 : :
3319 : 3 : ioch = spdk_accel_get_io_channel();
3320 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
3321 : 3 : rc = spdk_accel_set_driver("ut");
3322 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
3323 : :
3324 : : /* Override the submit_tasks function */
3325 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
3326 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3327 : 51 : modules[i] = g_modules_opc[i];
3328 : 51 : g_modules_opc[i] = g_module;
3329 : 17 : }
3330 : : /* Intercept crypto operations, as they should be executed by an accel module */
3331 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].submit = ut_submit_crypto;
3332 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].submit = ut_submit_crypto;
3333 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3334 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3335 : 3 : g_seq_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3336 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3337 : :
3338 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].supported = true;
3339 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].supported = true;
3340 : :
3341 : : /* First check a sequence that is fully executed using a driver, with the copy at the end
3342 : : * being removed */
3343 : 3 : seq = NULL;
3344 : 3 : completed = 0;
3345 : 3 : memset(buf, 0, sizeof(buf));
3346 : 3 : memset(tmp[0], 0, sizeof(tmp[0]));
3347 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
3348 : 3 : memset(&expected[0], 0xa5, 2048);
3349 : 3 : memset(&expected[2048], 0xbe, 2048);
3350 : :
3351 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], 2048, NULL, NULL, 0xa5,
3352 : : ut_sequence_step_cb, &completed);
3353 : 3 : CU_ASSERT_EQUAL(rc, 0);
3354 : 3 : rc = spdk_accel_append_fill(&seq, ioch, &tmp[0][2048], 2048, NULL, NULL, 0xbe,
3355 : : ut_sequence_step_cb, &completed);
3356 : 3 : CU_ASSERT_EQUAL(rc, 0);
3357 : :
3358 : 3 : dst_iovs[0].iov_base = tmp[1];
3359 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3360 : 3 : src_iovs[0].iov_base = tmp[0];
3361 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3362 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3363 : 1 : &src_iovs[0], 1, NULL, NULL,
3364 : : ut_sequence_step_cb, &completed);
3365 : 3 : CU_ASSERT_EQUAL(rc, 0);
3366 : :
3367 : 3 : dst_iovs[1].iov_base = buf;
3368 : 3 : dst_iovs[1].iov_len = sizeof(buf);
3369 : 3 : src_iovs[1].iov_base = tmp[1];
3370 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3371 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
3372 : 1 : &src_iovs[1], 1, NULL, NULL,
3373 : : ut_sequence_step_cb, &completed);
3374 : 3 : CU_ASSERT_EQUAL(rc, 0);
3375 : :
3376 : 3 : ut_seq.complete = false;
3377 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3378 : :
3379 : 3 : poll_threads();
3380 : :
3381 : 3 : CU_ASSERT_EQUAL(completed, 4);
3382 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3383 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3384 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3385 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 0);
3386 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
3387 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 2);
3388 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
3389 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3390 : :
3391 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3392 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3393 : :
3394 : : /* Check a sequence when the first two operations are executed by a driver, while the rest
3395 : : * is executed via modules */
3396 : 3 : seq = NULL;
3397 : 3 : completed = 0;
3398 : 3 : memset(buf, 0, sizeof(buf));
3399 : 3 : memset(tmp[0], 0, sizeof(tmp[0]));
3400 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
3401 : 3 : memset(tmp[2], 0, sizeof(tmp[2]));
3402 : 3 : memset(&expected[0], 0xfe, 4096);
3403 : :
3404 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], sizeof(tmp[0]), NULL, NULL, 0xfe,
3405 : : ut_sequence_step_cb, &completed);
3406 : 3 : CU_ASSERT_EQUAL(rc, 0);
3407 : :
3408 : 3 : dst_iovs[0].iov_base = tmp[1];
3409 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3410 : 3 : src_iovs[0].iov_base = tmp[0];
3411 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3412 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3413 : 1 : &src_iovs[0], 1, NULL, NULL,
3414 : : ut_sequence_step_cb, &completed);
3415 : 3 : CU_ASSERT_EQUAL(rc, 0);
3416 : :
3417 : 3 : dst_iovs[1].iov_base = tmp[2];
3418 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
3419 : 3 : src_iovs[1].iov_base = tmp[1];
3420 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3421 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
3422 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3423 : : ut_sequence_step_cb, &completed);
3424 : 3 : CU_ASSERT_EQUAL(rc, 0);
3425 : :
3426 : 3 : dst_iovs[2].iov_base = buf;
3427 : 3 : dst_iovs[2].iov_len = sizeof(buf);
3428 : 3 : src_iovs[2].iov_base = tmp[2];
3429 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
3430 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[2], 1, NULL, NULL,
3431 : 1 : &src_iovs[2], 1, NULL, NULL, 0, 4096,
3432 : : ut_sequence_step_cb, &completed);
3433 : 3 : CU_ASSERT_EQUAL(rc, 0);
3434 : :
3435 : 3 : ut_seq.complete = false;
3436 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3437 : :
3438 : 3 : poll_threads();
3439 : :
3440 : 3 : CU_ASSERT_EQUAL(completed, 4);
3441 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3442 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3443 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3444 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 0);
3445 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3446 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
3447 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3448 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
3449 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3450 : :
3451 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3452 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3453 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3454 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3455 : :
3456 : : /* Check sequence when the first and last operations are executed through modules, while the
3457 : : * ones in the middle are executed by the driver */
3458 : 3 : seq = NULL;
3459 : 3 : completed = 0;
3460 : 3 : memset(buf, 0, sizeof(buf));
3461 : 3 : memset(tmp[0], 0xa5, sizeof(tmp[0]));
3462 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
3463 : 3 : memset(tmp[2], 0, sizeof(tmp[2]));
3464 : 3 : memset(&expected[0], 0xfe, 2048);
3465 : 3 : memset(&expected[2048], 0xa5, 2048);
3466 : :
3467 : 3 : dst_iovs[0].iov_base = tmp[1];
3468 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3469 : 3 : src_iovs[0].iov_base = tmp[0];
3470 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3471 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[0], 1, NULL, NULL,
3472 : 1 : &src_iovs[0], 1, NULL, NULL, 0, 4096,
3473 : : ut_sequence_step_cb, &completed);
3474 : 3 : CU_ASSERT_EQUAL(rc, 0);
3475 : :
3476 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 2048, NULL, NULL, 0xfe,
3477 : : ut_sequence_step_cb, &completed);
3478 : 3 : CU_ASSERT_EQUAL(rc, 0);
3479 : :
3480 : 3 : dst_iovs[1].iov_base = tmp[2];
3481 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
3482 : 3 : src_iovs[1].iov_base = tmp[1];
3483 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3484 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
3485 : 1 : &src_iovs[1], 1, NULL, NULL,
3486 : : ut_sequence_step_cb, &completed);
3487 : 3 : CU_ASSERT_EQUAL(rc, 0);
3488 : :
3489 : 3 : dst_iovs[2].iov_base = buf;
3490 : 3 : dst_iovs[2].iov_len = sizeof(buf);
3491 : 3 : src_iovs[2].iov_base = tmp[2];
3492 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
3493 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[2], 1, NULL, NULL,
3494 : 1 : &src_iovs[2], 1, NULL, NULL, 0, 4096,
3495 : : ut_sequence_step_cb, &completed);
3496 : 3 : CU_ASSERT_EQUAL(rc, 0);
3497 : :
3498 : 3 : ut_seq.complete = false;
3499 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3500 : :
3501 : 3 : poll_threads();
3502 : :
3503 : 3 : CU_ASSERT_EQUAL(completed, 4);
3504 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3505 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3506 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3507 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 0);
3508 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3509 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
3510 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3511 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
3512 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3513 : :
3514 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3515 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3516 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3517 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3518 : :
3519 : : /* Check a sequence with operations executed by: module, driver, module, driver */
3520 : 3 : seq = NULL;
3521 : 3 : completed = 0;
3522 : 3 : memset(buf, 0, sizeof(buf));
3523 : 3 : memset(tmp[0], 0x5a, sizeof(tmp[0]));
3524 : 3 : memset(tmp[1], 0, sizeof(tmp[1]));
3525 : 3 : memset(tmp[2], 0, sizeof(tmp[2]));
3526 : 3 : memset(&expected[0], 0xef, 2048);
3527 : 3 : memset(&expected[2048], 0x5a, 2048);
3528 : :
3529 : 3 : dst_iovs[0].iov_base = tmp[1];
3530 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3531 : 3 : src_iovs[0].iov_base = tmp[0];
3532 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3533 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[0], 1, NULL, NULL,
3534 : 1 : &src_iovs[0], 1, NULL, NULL, 0, 4096,
3535 : : ut_sequence_step_cb, &completed);
3536 : 3 : CU_ASSERT_EQUAL(rc, 0);
3537 : :
3538 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 2048, NULL, NULL, 0xef,
3539 : : ut_sequence_step_cb, &completed);
3540 : 3 : CU_ASSERT_EQUAL(rc, 0);
3541 : :
3542 : 3 : dst_iovs[1].iov_base = tmp[2];
3543 : 3 : dst_iovs[1].iov_len = sizeof(tmp[2]);
3544 : 3 : src_iovs[1].iov_base = tmp[1];
3545 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3546 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
3547 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3548 : : ut_sequence_step_cb, &completed);
3549 : 3 : CU_ASSERT_EQUAL(rc, 0);
3550 : :
3551 : 3 : dst_iovs[2].iov_base = buf;
3552 : 3 : dst_iovs[2].iov_len = sizeof(buf);
3553 : 3 : src_iovs[2].iov_base = tmp[2];
3554 : 3 : src_iovs[2].iov_len = sizeof(tmp[2]);
3555 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
3556 : 1 : &src_iovs[2], 1, NULL, NULL,
3557 : : ut_sequence_step_cb, &completed);
3558 : 3 : CU_ASSERT_EQUAL(rc, 0);
3559 : :
3560 : 3 : ut_seq.complete = false;
3561 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3562 : :
3563 : 3 : poll_threads();
3564 : :
3565 : 3 : CU_ASSERT_EQUAL(completed, 4);
3566 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3567 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3568 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3569 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 0);
3570 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3571 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
3572 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3573 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
3574 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3575 : :
3576 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3577 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3578 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3579 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3580 : :
3581 : : /* Check that an error returned from driver's execute_sequence() will fail the whole
3582 : : * sequence and any subsequent operations won't be processed */
3583 : 3 : seq = NULL;
3584 : 3 : completed = 0;
3585 : 3 : memset(buf, 0, sizeof(buf));
3586 : 3 : memset(expected, 0, sizeof(expected));
3587 : 3 : memset(tmp[0], 0xa5, sizeof(tmp[0]));
3588 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].submit_status = -EPERM;
3589 : :
3590 : 3 : dst_iovs[0].iov_base = tmp[1];
3591 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3592 : 3 : src_iovs[0].iov_base = tmp[0];
3593 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3594 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[0], 1, NULL, NULL,
3595 : 1 : &src_iovs[0], 1, NULL, NULL, 0, 4096,
3596 : : ut_sequence_step_cb, &completed);
3597 : 3 : CU_ASSERT_EQUAL(rc, 0);
3598 : :
3599 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 2048, NULL, NULL, 0xef,
3600 : : ut_sequence_step_cb, &completed);
3601 : 3 : CU_ASSERT_EQUAL(rc, 0);
3602 : :
3603 : 3 : dst_iovs[1].iov_base = buf;
3604 : 3 : dst_iovs[1].iov_len = sizeof(buf);
3605 : 3 : src_iovs[1].iov_base = tmp[1];
3606 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3607 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
3608 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3609 : : ut_sequence_step_cb, &completed);
3610 : 3 : CU_ASSERT_EQUAL(rc, 0);
3611 : :
3612 : 3 : ut_seq.complete = false;
3613 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3614 : :
3615 : 3 : poll_threads();
3616 : :
3617 : 3 : CU_ASSERT_EQUAL(completed, 3);
3618 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3619 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -EPERM);
3620 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3621 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3622 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 0);
3623 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3624 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, 4096), 0);
3625 : :
3626 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3627 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3628 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].submit_status = 0;
3629 : :
3630 : : /* Check that a failed task completed by a driver will cause the whole sequence to be failed
3631 : : * and any subsequent operations won't be processed */
3632 : 3 : seq = NULL;
3633 : 3 : completed = 0;
3634 : 3 : memset(buf, 0, sizeof(buf));
3635 : 3 : memset(expected, 0, sizeof(expected));
3636 : 3 : memset(tmp[0], 0xa5, sizeof(tmp[0]));
3637 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].complete_status = -ENOENT;
3638 : :
3639 : 3 : dst_iovs[0].iov_base = tmp[1];
3640 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
3641 : 3 : src_iovs[0].iov_base = tmp[0];
3642 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3643 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &dst_iovs[0], 1, NULL, NULL,
3644 : 1 : &src_iovs[0], 1, NULL, NULL, 0, 4096,
3645 : : ut_sequence_step_cb, &completed);
3646 : 3 : CU_ASSERT_EQUAL(rc, 0);
3647 : :
3648 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[1], 2048, NULL, NULL, 0xef,
3649 : : ut_sequence_step_cb, &completed);
3650 : 3 : CU_ASSERT_EQUAL(rc, 0);
3651 : :
3652 : 3 : dst_iovs[1].iov_base = buf;
3653 : 3 : dst_iovs[1].iov_len = sizeof(buf);
3654 : 3 : src_iovs[1].iov_base = tmp[1];
3655 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
3656 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &dst_iovs[1], 1, NULL, NULL,
3657 : 1 : &src_iovs[1], 1, NULL, NULL, 0, 4096,
3658 : : ut_sequence_step_cb, &completed);
3659 : 3 : CU_ASSERT_EQUAL(rc, 0);
3660 : :
3661 : 3 : ut_seq.complete = false;
3662 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3663 : :
3664 : 3 : poll_threads();
3665 : :
3666 : 3 : CU_ASSERT_EQUAL(completed, 3);
3667 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3668 : 3 : CU_ASSERT_EQUAL(ut_seq.status, -ENOENT);
3669 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3670 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3671 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 0);
3672 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3673 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3674 : :
3675 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].complete_status = 0;
3676 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3677 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3678 : :
3679 : : /* Check asynchronous spdk_accel_sequence_continue() */
3680 : 3 : g_ut_driver_async_continue = true;
3681 : 3 : seq = NULL;
3682 : 3 : completed = 0;
3683 : 3 : memset(buf, 0, sizeof(buf));
3684 : 3 : memset(tmp[0], 0, sizeof(tmp[0]));
3685 : 3 : memset(&expected[0], 0xfe, 4096);
3686 : :
3687 : 3 : rc = spdk_accel_append_fill(&seq, ioch, tmp[0], sizeof(tmp[0]), NULL, NULL, 0xfe,
3688 : : ut_sequence_step_cb, &completed);
3689 : 3 : CU_ASSERT_EQUAL(rc, 0);
3690 : :
3691 : 3 : dst_iovs[0].iov_base = buf;
3692 : 3 : dst_iovs[0].iov_len = sizeof(buf);
3693 : 3 : src_iovs[0].iov_base = tmp[0];
3694 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3695 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3696 : 1 : &src_iovs[0], 1, NULL, NULL,
3697 : : ut_sequence_step_cb, &completed);
3698 : 3 : CU_ASSERT_EQUAL(rc, 0);
3699 : :
3700 : 3 : ut_seq.complete = false;
3701 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3702 : :
3703 : 3 : poll_threads();
3704 : :
3705 : 3 : CU_ASSERT_EQUAL(completed, 2);
3706 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3707 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3708 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_FILL].count, 0);
3709 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 0);
3710 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_FILL].count, 1);
3711 : 3 : CU_ASSERT_EQUAL(g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
3712 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3713 : :
3714 : 3 : g_drv_operations[SPDK_ACCEL_OPC_FILL].count = 0;
3715 : 3 : g_drv_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
3716 : :
3717 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3718 : 51 : g_modules_opc[i] = modules[i];
3719 : 17 : }
3720 : :
3721 : : /* Clear the driver so that other tests won't use it */
3722 : 3 : g_accel_driver = NULL;
3723 : 3 : memset(&g_drv_operations, 0, sizeof(g_drv_operations));
3724 : :
3725 : 3 : ut_clear_operations();
3726 : 3 : spdk_put_io_channel(ioch);
3727 : 3 : poll_threads();
3728 : 3 : }
3729 : :
3730 : : struct ut_saved_iovs {
3731 : : struct iovec src;
3732 : : struct iovec dst;
3733 : : };
3734 : :
3735 : : static struct ut_saved_iovs g_seq_saved_iovs[SPDK_ACCEL_OPC_LAST];
3736 : :
3737 : : static int
3738 : 12 : ut_submit_save_iovs(struct spdk_io_channel *ch, struct spdk_accel_task *task)
3739 : : {
3740 [ + + ]: 12 : SPDK_CU_ASSERT_FATAL(task->s.iovcnt == 1);
3741 [ - + ]: 12 : SPDK_CU_ASSERT_FATAL(task->d.iovcnt == 1);
3742 : :
3743 : 12 : g_seq_saved_iovs[task->op_code].src = task->s.iovs[0];
3744 : 12 : g_seq_saved_iovs[task->op_code].dst = task->d.iovs[0];
3745 : :
3746 : 12 : spdk_iovmove(task->s.iovs, task->s.iovcnt, task->d.iovs, task->d.iovcnt);
3747 : :
3748 : 12 : spdk_accel_task_complete(task, 0);
3749 : :
3750 : 12 : return 0;
3751 : : }
3752 : :
3753 : : static void
3754 : 3 : test_sequence_same_iovs(void)
3755 : : {
3756 : 3 : struct spdk_accel_sequence *seq = NULL;
3757 : : struct spdk_io_channel *ioch;
3758 : 3 : struct spdk_accel_crypto_key key = {};
3759 : 2 : struct ut_sequence ut_seq;
3760 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
3761 : 2 : char buf[4096], tmp[4096], expected[4096];
3762 : 2 : struct iovec iovs[3], expected_siov, expected_diov;
3763 : 2 : struct spdk_memory_domain *domain;
3764 : 2 : void *accel_buf, *domain_ctx;
3765 : 3 : int i, rc, completed = 0;
3766 : :
3767 : 3 : ioch = spdk_accel_get_io_channel();
3768 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
3769 : :
3770 : : /* Override the submit_tasks function */
3771 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
3772 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3773 : 51 : modules[i] = g_modules_opc[i];
3774 : 51 : g_modules_opc[i] = g_module;
3775 : 17 : }
3776 : : /* Intercept crypto operations, as they should be executed by an accel module */
3777 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].submit = ut_submit_save_iovs;
3778 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].submit = ut_submit_save_iovs;
3779 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3780 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3781 : :
3782 : : /* Check that it's possible to use the same iovec ptr for different operations */
3783 : 3 : seq = NULL;
3784 : 3 : completed = 0;
3785 : 3 : memset(buf, 0, sizeof(buf));
3786 : 3 : memset(expected, 0xa5, sizeof(expected));
3787 : :
3788 : 3 : iovs[0].iov_base = expected;
3789 : 3 : iovs[0].iov_len = sizeof(expected);
3790 : 3 : iovs[1].iov_base = tmp;
3791 : 3 : iovs[1].iov_len = sizeof(tmp);
3792 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &iovs[1], 1, NULL, NULL,
3793 : 1 : &iovs[0], 1, NULL, NULL, 0, 4096,
3794 : : ut_sequence_step_cb, &completed);
3795 : 3 : CU_ASSERT_EQUAL(rc, 0);
3796 : : /* Reuse iov[1] as src */
3797 : 3 : iovs[2].iov_base = buf;
3798 : 3 : iovs[2].iov_len = sizeof(buf);
3799 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &iovs[2], 1, NULL, NULL,
3800 : 1 : &iovs[1], 1, NULL, NULL, 0, 4096,
3801 : : ut_sequence_step_cb, &completed);
3802 : 3 : CU_ASSERT_EQUAL(rc, 0);
3803 : :
3804 : 3 : ut_seq.complete = false;
3805 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3806 : :
3807 : 3 : poll_threads();
3808 : :
3809 : 3 : CU_ASSERT_EQUAL(completed, 2);
3810 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3811 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3812 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3813 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
3814 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3815 : 3 : expected_siov.iov_base = expected;
3816 : 3 : expected_siov.iov_len = sizeof(expected);
3817 : 3 : expected_diov.iov_base = tmp;
3818 : 3 : expected_diov.iov_len = sizeof(tmp);
3819 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_ENCRYPT].src,
3820 : : &expected_siov, sizeof(expected_siov)), 0);
3821 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_ENCRYPT].dst,
3822 : : &expected_diov, sizeof(expected_diov)), 0);
3823 : 3 : expected_siov.iov_base = tmp;
3824 : 3 : expected_siov.iov_len = sizeof(tmp);
3825 : 3 : expected_diov.iov_base = buf;
3826 : 3 : expected_diov.iov_len = sizeof(buf);
3827 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_DECRYPT].src,
3828 : : &expected_siov, sizeof(expected_siov)), 0);
3829 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_DECRYPT].dst,
3830 : : &expected_diov, sizeof(expected_diov)), 0);
3831 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
3832 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
3833 : :
3834 : : /* Check the same with an accel buffer */
3835 : 3 : seq = NULL;
3836 : 3 : completed = 0;
3837 : 3 : memset(buf, 0, sizeof(buf));
3838 : 3 : memset(expected, 0x5a, sizeof(expected));
3839 : :
3840 : 3 : rc = spdk_accel_get_buf(ioch, sizeof(buf), &accel_buf, &domain, &domain_ctx);
3841 : 3 : CU_ASSERT_EQUAL(rc, 0);
3842 : :
3843 : 3 : iovs[0].iov_base = expected;
3844 : 3 : iovs[0].iov_len = sizeof(expected);
3845 : 3 : iovs[1].iov_base = accel_buf;
3846 : 3 : iovs[1].iov_len = sizeof(buf);
3847 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, &key, &iovs[1], 1, domain, domain_ctx,
3848 : 1 : &iovs[0], 1, NULL, NULL, 0, 4096,
3849 : : ut_sequence_step_cb, &completed);
3850 : 3 : CU_ASSERT_EQUAL(rc, 0);
3851 : : /* Reuse iov[1] as src */
3852 : 3 : iovs[2].iov_base = buf;
3853 : 3 : iovs[2].iov_len = sizeof(buf);
3854 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, &key, &iovs[2], 1, NULL, NULL,
3855 : 1 : &iovs[1], 1, domain, domain_ctx, 0, 4096,
3856 : : ut_sequence_step_cb, &completed);
3857 : 3 : CU_ASSERT_EQUAL(rc, 0);
3858 : :
3859 : 3 : ut_seq.complete = false;
3860 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3861 : :
3862 : 3 : poll_threads();
3863 : :
3864 : 3 : CU_ASSERT_EQUAL(completed, 2);
3865 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3866 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3867 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
3868 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
3869 : 3 : CU_ASSERT_EQUAL(memcmp(buf, expected, sizeof(buf)), 0);
3870 : 3 : expected_siov.iov_base = expected;
3871 : 3 : expected_siov.iov_len = sizeof(expected);
3872 : 3 : expected_diov.iov_base = buf;
3873 : 3 : expected_diov.iov_len = sizeof(buf);
3874 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_ENCRYPT].src,
3875 : : &expected_siov, sizeof(expected_siov)), 0);
3876 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_DECRYPT].dst,
3877 : : &expected_diov, sizeof(expected_diov)), 0);
3878 : 3 : CU_ASSERT_EQUAL(memcmp(&g_seq_saved_iovs[SPDK_ACCEL_OPC_ENCRYPT].dst,
3879 : : &g_seq_saved_iovs[SPDK_ACCEL_OPC_DECRYPT].src,
3880 : : sizeof(struct iovec)), 0);
3881 : 3 : spdk_accel_put_buf(ioch, accel_buf, domain, domain_ctx);
3882 : :
3883 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3884 : 51 : g_modules_opc[i] = modules[i];
3885 : 17 : }
3886 : :
3887 : 3 : ut_clear_operations();
3888 : 3 : spdk_put_io_channel(ioch);
3889 : 3 : poll_threads();
3890 : 3 : }
3891 : :
3892 : : static void
3893 : 3 : test_sequence_crc32(void)
3894 : : {
3895 : 3 : struct spdk_accel_sequence *seq = NULL;
3896 : : struct spdk_io_channel *ioch;
3897 : 2 : struct ut_sequence ut_seq;
3898 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
3899 : 2 : char buf[4096], tmp[3][4096];
3900 : 2 : struct iovec src_iovs[4], dst_iovs[4];
3901 : 2 : uint32_t crc, crc2;
3902 : 2 : int i, rc, completed;
3903 : :
3904 : 3 : ioch = spdk_accel_get_io_channel();
3905 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
3906 : :
3907 : : /* Override the submit_tasks function */
3908 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
3909 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
3910 : 51 : g_seq_operations[i].submit = sw_accel_submit_tasks;
3911 : 51 : modules[i] = g_modules_opc[i];
3912 : 51 : g_modules_opc[i] = g_module;
3913 : 17 : }
3914 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].submit = ut_submit_decompress;
3915 : :
3916 : : /* First check the simplest case - single crc32c operation */
3917 : 3 : seq = NULL;
3918 : 3 : completed = 0;
3919 : 3 : crc = 0;
3920 : 3 : memset(buf, 0xa5, sizeof(buf));
3921 : :
3922 : 3 : src_iovs[0].iov_base = buf;
3923 : 3 : src_iovs[0].iov_len = sizeof(buf);
3924 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc, &src_iovs[0], 1, NULL, NULL, 0,
3925 : : ut_sequence_step_cb, &completed);
3926 : 3 : CU_ASSERT_EQUAL(rc, 0);
3927 : :
3928 : 3 : ut_seq.complete = false;
3929 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3930 : :
3931 : 3 : poll_threads();
3932 : 3 : CU_ASSERT_EQUAL(completed, 1);
3933 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3934 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3935 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count, 1);
3936 : 3 : CU_ASSERT_EQUAL(crc, spdk_crc32c_update(buf, sizeof(buf), ~0u));
3937 : 3 : g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count = 0;
3938 : :
3939 : : /* Now check copy+crc - This should not remove the copy. Otherwise the data does not
3940 : : * end up where the user expected it to be. */
3941 : 3 : seq = NULL;
3942 : 3 : completed = 0;
3943 : 3 : crc = 0;
3944 : 3 : memset(buf, 0x5a, sizeof(buf));
3945 : 3 : memset(&tmp[0], 0, sizeof(tmp[0]));
3946 : :
3947 : 3 : dst_iovs[0].iov_base = tmp[0];
3948 : 3 : dst_iovs[0].iov_len = sizeof(tmp[0]);
3949 : 3 : src_iovs[0].iov_base = buf;
3950 : 3 : src_iovs[0].iov_len = sizeof(buf);
3951 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
3952 : 1 : &src_iovs[0], 1, NULL, NULL,
3953 : : ut_sequence_step_cb, &completed);
3954 : 3 : CU_ASSERT_EQUAL(rc, 0);
3955 : :
3956 : 3 : src_iovs[1].iov_base = tmp[0];
3957 : 3 : src_iovs[1].iov_len = sizeof(tmp[0]);
3958 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc, &src_iovs[1], 1, NULL, NULL, 0,
3959 : : ut_sequence_step_cb, &completed);
3960 : 3 : CU_ASSERT_EQUAL(rc, 0);
3961 : :
3962 : 3 : ut_seq.complete = false;
3963 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
3964 : :
3965 : 3 : poll_threads();
3966 : 3 : CU_ASSERT_EQUAL(completed, 2);
3967 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
3968 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
3969 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count, 1);
3970 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 1);
3971 : 3 : CU_ASSERT_EQUAL(memcmp(buf, tmp[0], sizeof(buf)), 0);
3972 : 3 : CU_ASSERT_EQUAL(crc, spdk_crc32c_update(buf, sizeof(buf), ~0u));
3973 : 3 : g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count = 0;
3974 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
3975 : :
3976 : : /* Check crc+copy - Again, the copy cannot be removed. */
3977 : 3 : seq = NULL;
3978 : 3 : completed = 0;
3979 : 3 : crc = 0;
3980 : 3 : memset(buf, 0, sizeof(buf));
3981 : 3 : memset(&tmp[0], 0xa5, sizeof(tmp[0]));
3982 : :
3983 : 3 : src_iovs[0].iov_base = tmp[0];
3984 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
3985 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc, &src_iovs[0], 1, NULL, NULL, 0,
3986 : : ut_sequence_step_cb, &completed);
3987 : 3 : CU_ASSERT_EQUAL(rc, 0);
3988 : :
3989 : 3 : dst_iovs[1].iov_base = buf;
3990 : 3 : dst_iovs[1].iov_len = sizeof(buf);
3991 : 3 : src_iovs[1].iov_base = tmp[0];
3992 : 3 : src_iovs[1].iov_len = sizeof(tmp[0]);
3993 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[1], 1, NULL, NULL,
3994 : 1 : &src_iovs[1], 1, NULL, NULL,
3995 : : ut_sequence_step_cb, &completed);
3996 : 3 : CU_ASSERT_EQUAL(rc, 0);
3997 : :
3998 : 3 : ut_seq.complete = false;
3999 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4000 : :
4001 : 3 : poll_threads();
4002 : 3 : CU_ASSERT_EQUAL(completed, 2);
4003 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4004 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4005 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count, 1);
4006 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 1);
4007 : 3 : CU_ASSERT_EQUAL(crc, spdk_crc32c_update(tmp[0], sizeof(tmp[0]), ~0u));
4008 : 3 : CU_ASSERT_EQUAL(memcmp(buf, tmp[0], sizeof(buf)), 0);
4009 : 3 : g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count = 0;
4010 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
4011 : :
4012 : : /* Check a sequence with an operation at the beginning that can have its buffer changed, two
4013 : : * crc operations and a copy at the end. The copy should be removed and the dst buffer of
4014 : : * the first operation and the src buffer of the crc operations should be changed.
4015 : : */
4016 : 3 : seq = NULL;
4017 : 3 : completed = 0;
4018 : 3 : crc = crc2 = 0;
4019 : 3 : memset(buf, 0, sizeof(buf));
4020 : 3 : memset(&tmp[0], 0x5a, sizeof(tmp[0]));
4021 : 3 : dst_iovs[0].iov_base = tmp[1];
4022 : 3 : dst_iovs[0].iov_len = sizeof(tmp[1]);
4023 : 3 : src_iovs[0].iov_base = tmp[0];
4024 : 3 : src_iovs[0].iov_len = sizeof(tmp[0]);
4025 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
4026 : 1 : &src_iovs[0], 1, NULL, NULL,
4027 : : ut_sequence_step_cb, &completed);
4028 : 3 : CU_ASSERT_EQUAL(rc, 0);
4029 : :
4030 : 3 : src_iovs[1].iov_base = tmp[1];
4031 : 3 : src_iovs[1].iov_len = sizeof(tmp[1]);
4032 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc, &src_iovs[1], 1, NULL, NULL, 0,
4033 : : ut_sequence_step_cb, &completed);
4034 : 3 : CU_ASSERT_EQUAL(rc, 0);
4035 : :
4036 : 3 : src_iovs[2].iov_base = tmp[1];
4037 : 3 : src_iovs[2].iov_len = sizeof(tmp[1]);
4038 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc2, &src_iovs[2], 1, NULL, NULL, 0,
4039 : : ut_sequence_step_cb, &completed);
4040 : 3 : CU_ASSERT_EQUAL(rc, 0);
4041 : :
4042 : 3 : dst_iovs[3].iov_base = buf;
4043 : 3 : dst_iovs[3].iov_len = sizeof(buf);
4044 : 3 : src_iovs[3].iov_base = tmp[1];
4045 : 3 : src_iovs[3].iov_len = sizeof(tmp[1]);
4046 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[3], 1, NULL, NULL,
4047 : 1 : &src_iovs[3], 1, NULL, NULL,
4048 : : ut_sequence_step_cb, &completed);
4049 : 3 : CU_ASSERT_EQUAL(rc, 0);
4050 : :
4051 : 3 : ut_seq.complete = false;
4052 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4053 : :
4054 : 3 : poll_threads();
4055 : 3 : CU_ASSERT_EQUAL(completed, 4);
4056 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4057 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4058 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
4059 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count, 2);
4060 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
4061 : 3 : CU_ASSERT_EQUAL(crc, spdk_crc32c_update(tmp[0], sizeof(tmp[0]), ~0u));
4062 : 3 : CU_ASSERT_EQUAL(crc, crc2);
4063 : 3 : CU_ASSERT_EQUAL(memcmp(buf, tmp[0], sizeof(buf)), 0);
4064 : 3 : g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count = 0;
4065 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
4066 : :
4067 : : /* Check that a copy won't be removed if the buffers don't match */
4068 : 3 : seq = NULL;
4069 : 3 : completed = 0;
4070 : 3 : crc = 0;
4071 : 3 : memset(buf, 0, sizeof(buf));
4072 : 3 : memset(&tmp[0], 0xa5, 2048);
4073 : 3 : memset(&tmp[1], 0xfe, sizeof(tmp[1]));
4074 : 3 : memset(&tmp[2], 0xfe, sizeof(tmp[1]));
4075 : 3 : dst_iovs[0].iov_base = &tmp[1][2048];
4076 : 3 : dst_iovs[0].iov_len = 2048;
4077 : 3 : src_iovs[0].iov_base = tmp[0];
4078 : 3 : src_iovs[0].iov_len = 2048;
4079 : 4 : rc = spdk_accel_append_decompress(&seq, ioch, &dst_iovs[0], 1, NULL, NULL,
4080 : 1 : &src_iovs[0], 1, NULL, NULL,
4081 : : ut_sequence_step_cb, &completed);
4082 : 3 : CU_ASSERT_EQUAL(rc, 0);
4083 : :
4084 : 3 : src_iovs[1].iov_base = &tmp[1][2048];
4085 : 3 : src_iovs[1].iov_len = 2048;
4086 : 3 : rc = spdk_accel_append_crc32c(&seq, ioch, &crc, &src_iovs[1], 1, NULL, NULL, 0,
4087 : : ut_sequence_step_cb, &completed);
4088 : 3 : CU_ASSERT_EQUAL(rc, 0);
4089 : :
4090 : 3 : dst_iovs[2].iov_base = buf;
4091 : 3 : dst_iovs[2].iov_len = sizeof(buf);
4092 : 3 : src_iovs[2].iov_base = tmp[1];
4093 : 3 : src_iovs[2].iov_len = sizeof(tmp[1]);
4094 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &dst_iovs[2], 1, NULL, NULL,
4095 : 1 : &src_iovs[2], 1, NULL, NULL,
4096 : : ut_sequence_step_cb, &completed);
4097 : 3 : CU_ASSERT_EQUAL(rc, 0);
4098 : :
4099 : 3 : ut_seq.complete = false;
4100 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4101 : :
4102 : 3 : poll_threads();
4103 : 3 : CU_ASSERT_EQUAL(completed, 3);
4104 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4105 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4106 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count, 1);
4107 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count, 1);
4108 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 1);
4109 : 3 : CU_ASSERT_EQUAL(crc, spdk_crc32c_update(tmp[0], 2048, ~0u));
4110 : 3 : CU_ASSERT_EQUAL(memcmp(buf, tmp[2], 2048), 0);
4111 : 3 : CU_ASSERT_EQUAL(memcmp(&buf[2048], tmp[0], 2048), 0);
4112 : 3 : g_seq_operations[SPDK_ACCEL_OPC_CRC32C].count = 0;
4113 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECOMPRESS].count = 0;
4114 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
4115 : :
4116 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
4117 : 51 : g_modules_opc[i] = modules[i];
4118 : 17 : }
4119 : :
4120 : 3 : ut_clear_operations();
4121 : 3 : spdk_put_io_channel(ioch);
4122 : 3 : poll_threads();
4123 : 3 : }
4124 : :
4125 : : static void
4126 : 3 : test_sequence_dix_generate_verify(void)
4127 : : {
4128 : 2 : struct spdk_accel_sequence *seq;
4129 : : struct spdk_io_channel *ioch;
4130 : 3 : struct ut_sequence ut_seq = {};
4131 : 2 : char srcbuf[3][4096], dstbuf[3][4096];
4132 : 2 : struct iovec src_iovs[3], dst_iovs[3];
4133 : 3 : uint32_t block_size = 512, md_size = 8;
4134 : 2 : struct spdk_dif_ctx_init_ext_opts dif_opts;
4135 : 3 : struct spdk_dif_ctx dif_ctx = {};
4136 : 2 : struct spdk_dif_error dif_err;
4137 : 3 : int i, rc, completed = 0;
4138 : :
4139 : 3 : ioch = spdk_accel_get_io_channel();
4140 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
4141 : :
4142 [ + + ]: 12 : for (i = 0; i < 3; i++) {
4143 [ - + ]: 9 : memset(srcbuf[i], 0xdead, sizeof(srcbuf[i]));
4144 [ - + ]: 9 : memset(dstbuf[i], 0, sizeof(dstbuf[i]));
4145 : 9 : src_iovs[i].iov_base = srcbuf[i];
4146 : 9 : src_iovs[i].iov_len = sizeof(srcbuf[i]);
4147 : 9 : dst_iovs[i].iov_base = dstbuf[i];
4148 : 9 : dst_iovs[i].iov_len = sizeof(dstbuf[i]);
4149 : 3 : }
4150 : :
4151 : 3 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
4152 : 3 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
4153 : :
4154 : 3 : rc = spdk_dif_ctx_init(&dif_ctx, block_size, md_size, false, true, SPDK_DIF_TYPE1,
4155 : : SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
4156 : : SPDK_DIF_FLAGS_REFTAG_CHECK, 10, 0xFFFF, 20, 0, 0, &dif_opts);
4157 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
4158 : :
4159 : 3 : seq = NULL;
4160 : 3 : completed = 0;
4161 [ + + ]: 12 : for (i = 0; i < 3; i++) {
4162 : 12 : rc = spdk_accel_append_dix_generate(&seq, ioch, &dst_iovs[i], 1, NULL, NULL,
4163 : 6 : &src_iovs[i], NULL, NULL,
4164 [ - + ]: 9 : src_iovs[i].iov_len / block_size, &dif_ctx,
4165 : : ut_sequence_step_cb, &completed);
4166 : 9 : CU_ASSERT_EQUAL(rc, 0);
4167 : 12 : rc = spdk_accel_append_dix_verify(&seq, ioch, &dst_iovs[i], 1, NULL, NULL,
4168 : 6 : &src_iovs[i], NULL, NULL,
4169 [ - + ]: 9 : src_iovs[i].iov_len / block_size, &dif_ctx,
4170 : : &dif_err, ut_sequence_step_cb, &completed);
4171 : 9 : CU_ASSERT_EQUAL(rc, 0);
4172 : 3 : }
4173 : :
4174 : 3 : ut_seq.complete = false;
4175 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4176 : :
4177 : 3 : poll_threads();
4178 : 3 : CU_ASSERT_EQUAL(completed, 6);
4179 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4180 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4181 : :
4182 : : /* DIX metadata should be equal for the same source buffers and tags */
4183 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf[0], dstbuf[1], 4096), 0);
4184 : 3 : CU_ASSERT_EQUAL(memcmp(dstbuf[0], dstbuf[2], 4096), 0);
4185 : :
4186 : 3 : ut_clear_operations();
4187 : 3 : spdk_put_io_channel(ioch);
4188 : 3 : poll_threads();
4189 : 3 : }
4190 : :
4191 : : static void
4192 : 3 : test_sequence_dix(void)
4193 : : {
4194 : 3 : struct spdk_accel_sequence *seq = NULL;
4195 : : struct spdk_io_channel *ioch;
4196 : 3 : struct ut_sequence ut_seq = {};
4197 : 2 : char buf[3][4096], md_buf[64];
4198 : 2 : struct iovec iovs[3], md_iov;
4199 : 3 : uint32_t block_size = 512, md_size = 8;
4200 : 2 : struct spdk_dif_ctx_init_ext_opts dif_opts;
4201 : 3 : struct spdk_dif_ctx dif_ctx = {};
4202 : 2 : struct spdk_dif_error dif_err;
4203 : : struct spdk_accel_crypto_key *key;
4204 : 3 : struct spdk_accel_crypto_key_create_param key_params = {
4205 : : .cipher = "AES_XTS",
4206 : : .hex_key = "00112233445566778899aabbccddeeff",
4207 : : .hex_key2 = "ffeeddccbbaa99887766554433221100",
4208 : : .key_name = "ut_key",
4209 : : };
4210 : 3 : int i, rc, completed = 0;
4211 : 2 : struct accel_module modules[SPDK_ACCEL_OPC_LAST];
4212 : :
4213 : 3 : ioch = spdk_accel_get_io_channel();
4214 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(ioch != NULL);
4215 : :
4216 : 3 : rc = spdk_accel_crypto_key_create(&key_params);
4217 : 3 : CU_ASSERT_EQUAL(rc, 0);
4218 : 3 : key = spdk_accel_crypto_key_get(key_params.key_name);
4219 [ + + ]: 3 : SPDK_CU_ASSERT_FATAL(key != NULL);
4220 : :
4221 : : /* Override the submit_tasks function. */
4222 : 3 : g_module_if.submit_tasks = ut_sequence_submit_tasks;
4223 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
4224 : 51 : g_seq_operations[i].complete_status = 0;
4225 : 51 : g_seq_operations[i].submit_status = 0;
4226 : 51 : g_seq_operations[i].count = 0;
4227 : :
4228 : 51 : modules[i] = g_modules_opc[i];
4229 : 51 : g_modules_opc[i] = g_module;
4230 : 17 : }
4231 : :
4232 [ + + ]: 12 : for (i = 0; i < 3; i++) {
4233 [ - + ]: 9 : memset(buf[i], 0, sizeof(buf[i]));
4234 : 9 : iovs[i].iov_base = buf[i];
4235 : 9 : iovs[i].iov_len = sizeof(buf[i]);
4236 : 3 : }
4237 [ - + ]: 3 : memset(md_buf, 0, sizeof(md_buf));
4238 : 3 : md_iov.iov_base = md_buf;
4239 : 3 : md_iov.iov_len = sizeof(md_buf);
4240 : :
4241 : : /* Prepare first source buffer. */
4242 [ - + ]: 3 : memset(iovs[0].iov_base, 0xde, iovs[0].iov_len);
4243 : :
4244 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
4245 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count = 0;
4246 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].dst_iovcnt = 1;
4247 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].src_iovcnt = 1;
4248 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].src_iovs = &iovs[0];
4249 : : /* Copy will be skipped, so the destination buffer of encrypt will change. */
4250 : 3 : g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].dst_iovs = &iovs[2];
4251 : :
4252 : 4 : rc = spdk_accel_append_encrypt(&seq, ioch, key, &iovs[1], 1, NULL, NULL,
4253 : 1 : &iovs[0], 1, NULL, NULL, 0, block_size,
4254 : : ut_sequence_step_cb, &completed);
4255 : 3 : CU_ASSERT_EQUAL(rc, 0);
4256 : :
4257 : 3 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
4258 : 3 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
4259 : :
4260 : 3 : rc = spdk_dif_ctx_init(&dif_ctx, block_size, md_size, false, true, SPDK_DIF_TYPE1,
4261 : : SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
4262 : : SPDK_DIF_FLAGS_REFTAG_CHECK, 10, 0xFFFF, 20, 0, 0, &dif_opts);
4263 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
4264 : :
4265 : 5 : rc = spdk_accel_append_dix_generate(&seq, ioch, &iovs[1], 1, NULL, NULL,
4266 [ - + ]: 3 : &md_iov, NULL, NULL, iovs[1].iov_len / block_size,
4267 : : &dif_ctx, ut_sequence_step_cb, &completed);
4268 : 3 : CU_ASSERT_EQUAL(rc, 0);
4269 : :
4270 : 4 : rc = spdk_accel_append_copy(&seq, ioch, &iovs[2], 1, NULL, NULL,
4271 : 1 : &iovs[1], 1, NULL, NULL,
4272 : : ut_sequence_step_cb, &completed);
4273 : 3 : CU_ASSERT_EQUAL(rc, 0);
4274 : :
4275 : 3 : ut_seq.complete = false;
4276 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4277 : :
4278 : 3 : poll_threads();
4279 : :
4280 : 3 : CU_ASSERT_EQUAL(completed, 3);
4281 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4282 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4283 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_ENCRYPT].count, 1);
4284 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
4285 : :
4286 : 3 : seq = NULL;
4287 : 3 : completed = 0;
4288 : :
4289 : : /* This time we start with first iovec containing encrypted data from previous sequence. */
4290 [ - + - + ]: 3 : memcpy(iovs[0].iov_base, iovs[2].iov_base, iovs[0].iov_len);
4291 : :
4292 : 3 : g_seq_operations[SPDK_ACCEL_OPC_COPY].count = 0;
4293 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count = 0;
4294 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovcnt = 1;
4295 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovcnt = 1;
4296 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].src_iovs = &iovs[0];
4297 : : /* Copy will be skipped, so the destination buffer of decrypt will change. */
4298 : 3 : g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].dst_iovs = &iovs[2];
4299 : :
4300 : 4 : rc = spdk_accel_append_decrypt(&seq, ioch, key, &iovs[1], 1, NULL, NULL,
4301 : 1 : &iovs[0], 1, NULL, NULL, 0, block_size,
4302 : : ut_sequence_step_cb, &completed);
4303 : 3 : CU_ASSERT_EQUAL(rc, 0);
4304 : :
4305 : 5 : rc = spdk_accel_append_dix_verify(&seq, ioch, &iovs[1], 1, NULL, NULL, &md_iov, NULL, NULL,
4306 [ - + ]: 3 : iovs[1].iov_len / block_size, &dif_ctx, &dif_err,
4307 : : ut_sequence_step_cb, &completed);
4308 : 3 : CU_ASSERT_EQUAL(rc, 0);
4309 : :
4310 : 3 : rc = spdk_accel_append_copy(&seq, ioch, &iovs[2], 1, NULL, NULL, &iovs[1], 1, NULL, NULL,
4311 : : ut_sequence_step_cb, &completed);
4312 : 3 : CU_ASSERT_EQUAL(rc, 0);
4313 : :
4314 : 3 : ut_seq.complete = false;
4315 : 3 : spdk_accel_sequence_finish(seq, ut_sequence_complete_cb, &ut_seq);
4316 : :
4317 : 3 : poll_threads();
4318 : :
4319 : 3 : CU_ASSERT_EQUAL(completed, 3);
4320 [ - + ]: 3 : CU_ASSERT(ut_seq.complete);
4321 : 3 : CU_ASSERT_EQUAL(ut_seq.status, 0);
4322 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_DECRYPT].count, 1);
4323 : 3 : CU_ASSERT_EQUAL(g_seq_operations[SPDK_ACCEL_OPC_COPY].count, 0);
4324 : :
4325 : 3 : ut_clear_operations();
4326 : :
4327 : : /* Cleanup module pointers to make subsequent tests work correctly. */
4328 [ + + ]: 54 : for (i = 0; i < SPDK_ACCEL_OPC_LAST; ++i) {
4329 : 51 : g_modules_opc[i] = modules[i];
4330 : 17 : }
4331 : :
4332 : 3 : rc = spdk_accel_crypto_key_destroy(key);
4333 : 3 : CU_ASSERT_EQUAL(rc, 0);
4334 : :
4335 : 3 : spdk_put_io_channel(ioch);
4336 : 3 : poll_threads();
4337 : 3 : }
4338 : :
4339 : : static int
4340 : 3 : test_sequence_setup(void)
4341 : : {
4342 : : int rc;
4343 : :
4344 : 3 : allocate_cores(1);
4345 : 3 : allocate_threads(1);
4346 : 3 : set_thread(0);
4347 : :
4348 : 3 : rc = spdk_iobuf_initialize();
4349 [ - + ]: 3 : if (rc != 0) {
4350 : 0 : CU_ASSERT(false);
4351 : 0 : return -1;
4352 : : }
4353 : :
4354 : 3 : rc = spdk_accel_initialize();
4355 [ + + ]: 3 : if (rc != 0) {
4356 : 0 : CU_ASSERT(false);
4357 : 0 : return -1;
4358 : : }
4359 : :
4360 : 3 : g_module_if.name = "software";
4361 : 3 : g_module_if.compress_supports_algo = _supports_algo;
4362 : 3 : g_module_if.get_compress_level_range = _get_compress_level_range;
4363 : :
4364 : 3 : return 0;
4365 : 1 : }
4366 : :
4367 : : static void
4368 : 6 : finish_cb(void *cb_arg)
4369 : : {
4370 : 6 : bool *done = cb_arg;
4371 : :
4372 : 6 : *done = true;
4373 : 6 : }
4374 : :
4375 : : static int
4376 : 3 : test_sequence_cleanup(void)
4377 : : {
4378 : 3 : bool done = false;
4379 : :
4380 : 3 : spdk_accel_finish(finish_cb, &done);
4381 : :
4382 [ + + + + ]: 6 : while (!done) {
4383 : 3 : poll_threads();
4384 : : }
4385 : :
4386 : 3 : done = false;
4387 : 3 : spdk_iobuf_finish(finish_cb, &done);
4388 [ - + - + ]: 3 : while (!done) {
4389 : 0 : poll_threads();
4390 : : }
4391 : :
4392 : 3 : free_threads();
4393 : 3 : free_cores();
4394 : :
4395 : 3 : return 0;
4396 : : }
4397 : :
4398 : : int
4399 : 3 : main(int argc, char **argv)
4400 : : {
4401 : 3 : CU_pSuite suite = NULL, seq_suite;
4402 : : unsigned int num_failures;
4403 : :
4404 : 3 : CU_initialize_registry();
4405 : :
4406 : : /* Sequence tests require accel to be initialized normally, so run them before the other
4407 : : * tests which register accel modules which aren't fully implemented, causing accel
4408 : : * initialization to fail.
4409 : : */
4410 : 3 : seq_suite = CU_add_suite("accel_sequence", test_sequence_setup, test_sequence_cleanup);
4411 : 3 : CU_ADD_TEST(seq_suite, test_sequence_fill_copy);
4412 : 3 : CU_ADD_TEST(seq_suite, test_sequence_abort);
4413 : 3 : CU_ADD_TEST(seq_suite, test_sequence_append_error);
4414 : 3 : CU_ADD_TEST(seq_suite, test_sequence_completion_error);
4415 : : #ifdef SPDK_CONFIG_ISAL /* accel_sw requires isa-l for compression */
4416 : 3 : CU_ADD_TEST(seq_suite, test_sequence_decompress);
4417 : 3 : CU_ADD_TEST(seq_suite, test_sequence_reverse);
4418 : : #endif
4419 : 3 : CU_ADD_TEST(seq_suite, test_sequence_copy_elision);
4420 : 3 : CU_ADD_TEST(seq_suite, test_sequence_accel_buffers);
4421 : 3 : CU_ADD_TEST(seq_suite, test_sequence_memory_domain);
4422 : 3 : CU_ADD_TEST(seq_suite, test_sequence_module_memory_domain);
4423 : : #ifdef SPDK_CONFIG_ISAL_CRYPTO /* accel_sw requires isa-l-crypto for crypto operations */
4424 : 3 : CU_ADD_TEST(seq_suite, test_sequence_crypto);
4425 : : #endif
4426 : 3 : CU_ADD_TEST(seq_suite, test_sequence_driver);
4427 : 3 : CU_ADD_TEST(seq_suite, test_sequence_same_iovs);
4428 : 3 : CU_ADD_TEST(seq_suite, test_sequence_crc32);
4429 : 3 : CU_ADD_TEST(seq_suite, test_sequence_dix_generate_verify);
4430 : 3 : CU_ADD_TEST(seq_suite, test_sequence_dix);
4431 : :
4432 : 3 : suite = CU_add_suite("accel", test_setup, test_cleanup);
4433 : 3 : CU_ADD_TEST(suite, test_spdk_accel_task_complete);
4434 : 3 : CU_ADD_TEST(suite, test_get_task);
4435 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_copy);
4436 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_dualcast);
4437 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_compare);
4438 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_fill);
4439 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_crc32c);
4440 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_crc32cv);
4441 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_copy_crc32c);
4442 : 3 : CU_ADD_TEST(suite, test_spdk_accel_submit_xor);
4443 : 3 : CU_ADD_TEST(suite, test_spdk_accel_module_find_by_name);
4444 : 3 : CU_ADD_TEST(suite, test_spdk_accel_module_register);
4445 : :
4446 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
4447 : 3 : CU_cleanup_registry();
4448 : :
4449 : 3 : return num_failures;
4450 : : }
|