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