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