test/compress: add stateful decompression
[dpdk.git] / app / test / test_compressdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 - 2019 Intel Corporation
3  */
4 #include <string.h>
5 #include <zlib.h>
6 #include <math.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9
10 #include <rte_cycles.h>
11 #include <rte_malloc.h>
12 #include <rte_mempool.h>
13 #include <rte_mbuf.h>
14 #include <rte_compressdev.h>
15 #include <rte_string_fns.h>
16
17 #include "test_compressdev_test_buffer.h"
18 #include "test.h"
19
20 #define DIV_CEIL(a, b)  ((a) / (b) + ((a) % (b) != 0))
21
22 #define DEFAULT_WINDOW_SIZE 15
23 #define DEFAULT_MEM_LEVEL 8
24 #define MAX_DEQD_RETRIES 10
25 #define DEQUEUE_WAIT_TIME 10000
26
27 /*
28  * 30% extra size for compressed data compared to original data,
29  * in case data size cannot be reduced and it is actually bigger
30  * due to the compress block headers
31  */
32 #define COMPRESS_BUF_SIZE_RATIO 1.3
33 #define NUM_LARGE_MBUFS 16
34 #define SMALL_SEG_SIZE 256
35 #define MAX_SEGS 16
36 #define NUM_OPS 16
37 #define NUM_MAX_XFORMS 16
38 #define NUM_MAX_INFLIGHT_OPS 128
39 #define CACHE_SIZE 0
40
41 #define ZLIB_CRC_CHECKSUM_WINDOW_BITS 31
42 #define ZLIB_HEADER_SIZE 2
43 #define ZLIB_TRAILER_SIZE 4
44 #define GZIP_HEADER_SIZE 10
45 #define GZIP_TRAILER_SIZE 8
46
47 #define OUT_OF_SPACE_BUF 1
48
49 #define MAX_MBUF_SEGMENT_SIZE 65535
50 #define MAX_DATA_MBUF_SIZE (MAX_MBUF_SEGMENT_SIZE - RTE_PKTMBUF_HEADROOM)
51 #define NUM_BIG_MBUFS 4
52 #define BIG_DATA_TEST_SIZE (MAX_DATA_MBUF_SIZE * NUM_BIG_MBUFS / 2)
53
54 const char *
55 huffman_type_strings[] = {
56         [RTE_COMP_HUFFMAN_DEFAULT]      = "PMD default",
57         [RTE_COMP_HUFFMAN_FIXED]        = "Fixed",
58         [RTE_COMP_HUFFMAN_DYNAMIC]      = "Dynamic"
59 };
60
61 enum zlib_direction {
62         ZLIB_NONE,
63         ZLIB_COMPRESS,
64         ZLIB_DECOMPRESS,
65         ZLIB_ALL
66 };
67
68 enum varied_buff {
69         LB_BOTH = 0,    /* both input and output are linear*/
70         SGL_BOTH,       /* both input and output are chained */
71         SGL_TO_LB,      /* input buffer is chained */
72         LB_TO_SGL       /* output buffer is chained */
73 };
74
75 struct priv_op_data {
76         uint16_t orig_idx;
77 };
78
79 struct comp_testsuite_params {
80         struct rte_mempool *large_mbuf_pool;
81         struct rte_mempool *small_mbuf_pool;
82         struct rte_mempool *big_mbuf_pool;
83         struct rte_mempool *op_pool;
84         struct rte_comp_xform *def_comp_xform;
85         struct rte_comp_xform *def_decomp_xform;
86 };
87
88 struct interim_data_params {
89         const char * const *test_bufs;
90         unsigned int num_bufs;
91         uint16_t *buf_idx;
92         struct rte_comp_xform **compress_xforms;
93         struct rte_comp_xform **decompress_xforms;
94         unsigned int num_xforms;
95 };
96
97 struct test_data_params {
98         enum rte_comp_op_type compress_state;
99         enum rte_comp_op_type decompress_state;
100         enum varied_buff buff_type;
101         enum zlib_direction zlib_dir;
102         unsigned int out_of_space;
103         unsigned int big_data;
104         /* stateful decompression specific parameters */
105         unsigned int decompress_output_block_size;
106         unsigned int decompress_steps_max;
107 };
108
109 static struct comp_testsuite_params testsuite_params = { 0 };
110
111 static void
112 testsuite_teardown(void)
113 {
114         struct comp_testsuite_params *ts_params = &testsuite_params;
115
116         if (rte_mempool_in_use_count(ts_params->large_mbuf_pool))
117                 RTE_LOG(ERR, USER1, "Large mbuf pool still has unfreed bufs\n");
118         if (rte_mempool_in_use_count(ts_params->small_mbuf_pool))
119                 RTE_LOG(ERR, USER1, "Small mbuf pool still has unfreed bufs\n");
120         if (rte_mempool_in_use_count(ts_params->big_mbuf_pool))
121                 RTE_LOG(ERR, USER1, "Big mbuf pool still has unfreed bufs\n");
122         if (rte_mempool_in_use_count(ts_params->op_pool))
123                 RTE_LOG(ERR, USER1, "op pool still has unfreed ops\n");
124
125         rte_mempool_free(ts_params->large_mbuf_pool);
126         rte_mempool_free(ts_params->small_mbuf_pool);
127         rte_mempool_free(ts_params->big_mbuf_pool);
128         rte_mempool_free(ts_params->op_pool);
129         rte_free(ts_params->def_comp_xform);
130         rte_free(ts_params->def_decomp_xform);
131 }
132
133 static int
134 testsuite_setup(void)
135 {
136         struct comp_testsuite_params *ts_params = &testsuite_params;
137         uint32_t max_buf_size = 0;
138         unsigned int i;
139
140         if (rte_compressdev_count() == 0) {
141                 RTE_LOG(WARNING, USER1, "Need at least one compress device\n");
142                 return TEST_SKIPPED;
143         }
144
145         RTE_LOG(NOTICE, USER1, "Running tests on device %s\n",
146                                 rte_compressdev_name_get(0));
147
148         for (i = 0; i < RTE_DIM(compress_test_bufs); i++)
149                 max_buf_size = RTE_MAX(max_buf_size,
150                                 strlen(compress_test_bufs[i]) + 1);
151
152         /*
153          * Buffers to be used in compression and decompression.
154          * Since decompressed data might be larger than
155          * compressed data (due to block header),
156          * buffers should be big enough for both cases.
157          */
158         max_buf_size *= COMPRESS_BUF_SIZE_RATIO;
159         ts_params->large_mbuf_pool = rte_pktmbuf_pool_create("large_mbuf_pool",
160                         NUM_LARGE_MBUFS,
161                         CACHE_SIZE, 0,
162                         max_buf_size + RTE_PKTMBUF_HEADROOM,
163                         rte_socket_id());
164         if (ts_params->large_mbuf_pool == NULL) {
165                 RTE_LOG(ERR, USER1, "Large mbuf pool could not be created\n");
166                 return TEST_FAILED;
167         }
168
169         /* Create mempool with smaller buffers for SGL testing */
170         ts_params->small_mbuf_pool = rte_pktmbuf_pool_create("small_mbuf_pool",
171                         NUM_LARGE_MBUFS * MAX_SEGS,
172                         CACHE_SIZE, 0,
173                         SMALL_SEG_SIZE + RTE_PKTMBUF_HEADROOM,
174                         rte_socket_id());
175         if (ts_params->small_mbuf_pool == NULL) {
176                 RTE_LOG(ERR, USER1, "Small mbuf pool could not be created\n");
177                 goto exit;
178         }
179
180         /* Create mempool with big buffers for SGL testing */
181         ts_params->big_mbuf_pool = rte_pktmbuf_pool_create("big_mbuf_pool",
182                         NUM_BIG_MBUFS + 1,
183                         CACHE_SIZE, 0,
184                         MAX_MBUF_SEGMENT_SIZE,
185                         rte_socket_id());
186         if (ts_params->big_mbuf_pool == NULL) {
187                 RTE_LOG(ERR, USER1, "Big mbuf pool could not be created\n");
188                 goto exit;
189         }
190
191         ts_params->op_pool = rte_comp_op_pool_create("op_pool", NUM_OPS,
192                                 0, sizeof(struct priv_op_data),
193                                 rte_socket_id());
194         if (ts_params->op_pool == NULL) {
195                 RTE_LOG(ERR, USER1, "Operation pool could not be created\n");
196                 goto exit;
197         }
198
199         ts_params->def_comp_xform =
200                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
201         if (ts_params->def_comp_xform == NULL) {
202                 RTE_LOG(ERR, USER1,
203                         "Default compress xform could not be created\n");
204                 goto exit;
205         }
206         ts_params->def_decomp_xform =
207                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
208         if (ts_params->def_decomp_xform == NULL) {
209                 RTE_LOG(ERR, USER1,
210                         "Default decompress xform could not be created\n");
211                 goto exit;
212         }
213
214         /* Initializes default values for compress/decompress xforms */
215         ts_params->def_comp_xform->type = RTE_COMP_COMPRESS;
216         ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE,
217         ts_params->def_comp_xform->compress.deflate.huffman =
218                                                 RTE_COMP_HUFFMAN_DEFAULT;
219         ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_PMD_DEFAULT;
220         ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE;
221         ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE;
222
223         ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS;
224         ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE,
225         ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE;
226         ts_params->def_decomp_xform->decompress.window_size = DEFAULT_WINDOW_SIZE;
227
228         return TEST_SUCCESS;
229
230 exit:
231         testsuite_teardown();
232
233         return TEST_FAILED;
234 }
235
236 static int
237 generic_ut_setup(void)
238 {
239         /* Configure compressdev (one device, one queue pair) */
240         struct rte_compressdev_config config = {
241                 .socket_id = rte_socket_id(),
242                 .nb_queue_pairs = 1,
243                 .max_nb_priv_xforms = NUM_MAX_XFORMS,
244                 .max_nb_streams = 1
245         };
246
247         if (rte_compressdev_configure(0, &config) < 0) {
248                 RTE_LOG(ERR, USER1, "Device configuration failed\n");
249                 return -1;
250         }
251
252         if (rte_compressdev_queue_pair_setup(0, 0, NUM_MAX_INFLIGHT_OPS,
253                         rte_socket_id()) < 0) {
254                 RTE_LOG(ERR, USER1, "Queue pair setup failed\n");
255                 return -1;
256         }
257
258         if (rte_compressdev_start(0) < 0) {
259                 RTE_LOG(ERR, USER1, "Device could not be started\n");
260                 return -1;
261         }
262
263         return 0;
264 }
265
266 static void
267 generic_ut_teardown(void)
268 {
269         rte_compressdev_stop(0);
270         if (rte_compressdev_close(0) < 0)
271                 RTE_LOG(ERR, USER1, "Device could not be closed\n");
272 }
273
274 static int
275 test_compressdev_invalid_configuration(void)
276 {
277         struct rte_compressdev_config invalid_config;
278         struct rte_compressdev_config valid_config = {
279                 .socket_id = rte_socket_id(),
280                 .nb_queue_pairs = 1,
281                 .max_nb_priv_xforms = NUM_MAX_XFORMS,
282                 .max_nb_streams = 1
283         };
284         struct rte_compressdev_info dev_info;
285
286         /* Invalid configuration with 0 queue pairs */
287         memcpy(&invalid_config, &valid_config,
288                         sizeof(struct rte_compressdev_config));
289         invalid_config.nb_queue_pairs = 0;
290
291         TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config),
292                         "Device configuration was successful "
293                         "with no queue pairs (invalid)\n");
294
295         /*
296          * Invalid configuration with too many queue pairs
297          * (if there is an actual maximum number of queue pairs)
298          */
299         rte_compressdev_info_get(0, &dev_info);
300         if (dev_info.max_nb_queue_pairs != 0) {
301                 memcpy(&invalid_config, &valid_config,
302                         sizeof(struct rte_compressdev_config));
303                 invalid_config.nb_queue_pairs = dev_info.max_nb_queue_pairs + 1;
304
305                 TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config),
306                                 "Device configuration was successful "
307                                 "with too many queue pairs (invalid)\n");
308         }
309
310         /* Invalid queue pair setup, with no number of queue pairs set */
311         TEST_ASSERT_FAIL(rte_compressdev_queue_pair_setup(0, 0,
312                                 NUM_MAX_INFLIGHT_OPS, rte_socket_id()),
313                         "Queue pair setup was successful "
314                         "with no queue pairs set (invalid)\n");
315
316         return TEST_SUCCESS;
317 }
318
319 static int
320 compare_buffers(const char *buffer1, uint32_t buffer1_len,
321                 const char *buffer2, uint32_t buffer2_len)
322 {
323         if (buffer1_len != buffer2_len) {
324                 RTE_LOG(ERR, USER1, "Buffer lengths are different\n");
325                 return -1;
326         }
327
328         if (memcmp(buffer1, buffer2, buffer1_len) != 0) {
329                 RTE_LOG(ERR, USER1, "Buffers are different\n");
330                 return -1;
331         }
332
333         return 0;
334 }
335
336 /*
337  * Maps compressdev and Zlib flush flags
338  */
339 static int
340 map_zlib_flush_flag(enum rte_comp_flush_flag flag)
341 {
342         switch (flag) {
343         case RTE_COMP_FLUSH_NONE:
344                 return Z_NO_FLUSH;
345         case RTE_COMP_FLUSH_SYNC:
346                 return Z_SYNC_FLUSH;
347         case RTE_COMP_FLUSH_FULL:
348                 return Z_FULL_FLUSH;
349         case RTE_COMP_FLUSH_FINAL:
350                 return Z_FINISH;
351         /*
352          * There should be only the values above,
353          * so this should never happen
354          */
355         default:
356                 return -1;
357         }
358 }
359
360 static int
361 compress_zlib(struct rte_comp_op *op,
362                 const struct rte_comp_xform *xform, int mem_level)
363 {
364         z_stream stream;
365         int zlib_flush;
366         int strategy, window_bits, comp_level;
367         int ret = TEST_FAILED;
368         uint8_t *single_src_buf = NULL;
369         uint8_t *single_dst_buf = NULL;
370
371         /* initialize zlib stream */
372         stream.zalloc = Z_NULL;
373         stream.zfree = Z_NULL;
374         stream.opaque = Z_NULL;
375
376         if (xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED)
377                 strategy = Z_FIXED;
378         else
379                 strategy = Z_DEFAULT_STRATEGY;
380
381         /*
382          * Window bits is the base two logarithm of the window size (in bytes).
383          * When doing raw DEFLATE, this number will be negative.
384          */
385         window_bits = -(xform->compress.window_size);
386         if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32)
387                 window_bits *= -1;
388         else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32)
389                 window_bits = ZLIB_CRC_CHECKSUM_WINDOW_BITS;
390
391         comp_level = xform->compress.level;
392
393         if (comp_level != RTE_COMP_LEVEL_NONE)
394                 ret = deflateInit2(&stream, comp_level, Z_DEFLATED,
395                         window_bits, mem_level, strategy);
396         else
397                 ret = deflateInit(&stream, Z_NO_COMPRESSION);
398
399         if (ret != Z_OK) {
400                 printf("Zlib deflate could not be initialized\n");
401                 goto exit;
402         }
403
404         /* Assuming stateless operation */
405         /* SGL Input */
406         if (op->m_src->nb_segs > 1) {
407                 single_src_buf = rte_malloc(NULL,
408                                 rte_pktmbuf_pkt_len(op->m_src), 0);
409                 if (single_src_buf == NULL) {
410                         RTE_LOG(ERR, USER1, "Buffer could not be allocated\n");
411                         goto exit;
412                 }
413
414                 if (rte_pktmbuf_read(op->m_src, op->src.offset,
415                                         rte_pktmbuf_pkt_len(op->m_src) -
416                                         op->src.offset,
417                                         single_src_buf) == NULL) {
418                         RTE_LOG(ERR, USER1,
419                                 "Buffer could not be read entirely\n");
420                         goto exit;
421                 }
422
423                 stream.avail_in = op->src.length;
424                 stream.next_in = single_src_buf;
425
426         } else {
427                 stream.avail_in = op->src.length;
428                 stream.next_in = rte_pktmbuf_mtod_offset(op->m_src, uint8_t *,
429                                 op->src.offset);
430         }
431         /* SGL output */
432         if (op->m_dst->nb_segs > 1) {
433
434                 single_dst_buf = rte_malloc(NULL,
435                                 rte_pktmbuf_pkt_len(op->m_dst), 0);
436                         if (single_dst_buf == NULL) {
437                                 RTE_LOG(ERR, USER1,
438                                         "Buffer could not be allocated\n");
439                         goto exit;
440                 }
441
442                 stream.avail_out = op->m_dst->pkt_len;
443                 stream.next_out = single_dst_buf;
444
445         } else {/* linear output */
446                 stream.avail_out = op->m_dst->data_len;
447                 stream.next_out = rte_pktmbuf_mtod_offset(op->m_dst, uint8_t *,
448                                 op->dst.offset);
449         }
450
451         /* Stateless operation, all buffer will be compressed in one go */
452         zlib_flush = map_zlib_flush_flag(op->flush_flag);
453         ret = deflate(&stream, zlib_flush);
454
455         if (stream.avail_in != 0) {
456                 RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n");
457                 goto exit;
458         }
459
460         if (ret != Z_STREAM_END)
461                 goto exit;
462
463         /* Copy data to destination SGL */
464         if (op->m_dst->nb_segs > 1) {
465                 uint32_t remaining_data = stream.total_out;
466                 uint8_t *src_data = single_dst_buf;
467                 struct rte_mbuf *dst_buf = op->m_dst;
468
469                 while (remaining_data > 0) {
470                         uint8_t *dst_data = rte_pktmbuf_mtod_offset(dst_buf,
471                                                 uint8_t *, op->dst.offset);
472                         /* Last segment */
473                         if (remaining_data < dst_buf->data_len) {
474                                 memcpy(dst_data, src_data, remaining_data);
475                                 remaining_data = 0;
476                         } else {
477                                 memcpy(dst_data, src_data, dst_buf->data_len);
478                                 remaining_data -= dst_buf->data_len;
479                                 src_data += dst_buf->data_len;
480                                 dst_buf = dst_buf->next;
481                         }
482                 }
483         }
484
485         op->consumed = stream.total_in;
486         if (xform->compress.chksum == RTE_COMP_CHECKSUM_ADLER32) {
487                 rte_pktmbuf_adj(op->m_dst, ZLIB_HEADER_SIZE);
488                 rte_pktmbuf_trim(op->m_dst, ZLIB_TRAILER_SIZE);
489                 op->produced = stream.total_out - (ZLIB_HEADER_SIZE +
490                                 ZLIB_TRAILER_SIZE);
491         } else if (xform->compress.chksum == RTE_COMP_CHECKSUM_CRC32) {
492                 rte_pktmbuf_adj(op->m_dst, GZIP_HEADER_SIZE);
493                 rte_pktmbuf_trim(op->m_dst, GZIP_TRAILER_SIZE);
494                 op->produced = stream.total_out - (GZIP_HEADER_SIZE +
495                                 GZIP_TRAILER_SIZE);
496         } else
497                 op->produced = stream.total_out;
498
499         op->status = RTE_COMP_OP_STATUS_SUCCESS;
500         op->output_chksum = stream.adler;
501
502         deflateReset(&stream);
503
504         ret = 0;
505 exit:
506         deflateEnd(&stream);
507         rte_free(single_src_buf);
508         rte_free(single_dst_buf);
509
510         return ret;
511 }
512
513 static int
514 decompress_zlib(struct rte_comp_op *op,
515                 const struct rte_comp_xform *xform)
516 {
517         z_stream stream;
518         int window_bits;
519         int zlib_flush;
520         int ret = TEST_FAILED;
521         uint8_t *single_src_buf = NULL;
522         uint8_t *single_dst_buf = NULL;
523
524         /* initialize zlib stream */
525         stream.zalloc = Z_NULL;
526         stream.zfree = Z_NULL;
527         stream.opaque = Z_NULL;
528
529         /*
530          * Window bits is the base two logarithm of the window size (in bytes).
531          * When doing raw DEFLATE, this number will be negative.
532          */
533         window_bits = -(xform->decompress.window_size);
534         ret = inflateInit2(&stream, window_bits);
535
536         if (ret != Z_OK) {
537                 printf("Zlib deflate could not be initialized\n");
538                 goto exit;
539         }
540
541         /* Assuming stateless operation */
542         /* SGL */
543         if (op->m_src->nb_segs > 1) {
544                 single_src_buf = rte_malloc(NULL,
545                                 rte_pktmbuf_pkt_len(op->m_src), 0);
546                 if (single_src_buf == NULL) {
547                         RTE_LOG(ERR, USER1, "Buffer could not be allocated\n");
548                         goto exit;
549                 }
550                 single_dst_buf = rte_malloc(NULL,
551                                 rte_pktmbuf_pkt_len(op->m_dst), 0);
552                 if (single_dst_buf == NULL) {
553                         RTE_LOG(ERR, USER1, "Buffer could not be allocated\n");
554                         goto exit;
555                 }
556                 if (rte_pktmbuf_read(op->m_src, 0,
557                                         rte_pktmbuf_pkt_len(op->m_src),
558                                         single_src_buf) == NULL) {
559                         RTE_LOG(ERR, USER1,
560                                 "Buffer could not be read entirely\n");
561                         goto exit;
562                 }
563
564                 stream.avail_in = op->src.length;
565                 stream.next_in = single_src_buf;
566                 stream.avail_out = rte_pktmbuf_pkt_len(op->m_dst);
567                 stream.next_out = single_dst_buf;
568
569         } else {
570                 stream.avail_in = op->src.length;
571                 stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *);
572                 stream.avail_out = op->m_dst->data_len;
573                 stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *);
574         }
575
576         /* Stateless operation, all buffer will be compressed in one go */
577         zlib_flush = map_zlib_flush_flag(op->flush_flag);
578         ret = inflate(&stream, zlib_flush);
579
580         if (stream.avail_in != 0) {
581                 RTE_LOG(ERR, USER1, "Buffer could not be read entirely\n");
582                 goto exit;
583         }
584
585         if (ret != Z_STREAM_END)
586                 goto exit;
587
588         if (op->m_src->nb_segs > 1) {
589                 uint32_t remaining_data = stream.total_out;
590                 uint8_t *src_data = single_dst_buf;
591                 struct rte_mbuf *dst_buf = op->m_dst;
592
593                 while (remaining_data > 0) {
594                         uint8_t *dst_data = rte_pktmbuf_mtod(dst_buf,
595                                         uint8_t *);
596                         /* Last segment */
597                         if (remaining_data < dst_buf->data_len) {
598                                 memcpy(dst_data, src_data, remaining_data);
599                                 remaining_data = 0;
600                         } else {
601                                 memcpy(dst_data, src_data, dst_buf->data_len);
602                                 remaining_data -= dst_buf->data_len;
603                                 src_data += dst_buf->data_len;
604                                 dst_buf = dst_buf->next;
605                         }
606                 }
607         }
608
609         op->consumed = stream.total_in;
610         op->produced = stream.total_out;
611         op->status = RTE_COMP_OP_STATUS_SUCCESS;
612
613         inflateReset(&stream);
614
615         ret = 0;
616 exit:
617         inflateEnd(&stream);
618
619         return ret;
620 }
621
622 static int
623 prepare_sgl_bufs(const char *test_buf, struct rte_mbuf *head_buf,
624                 uint32_t total_data_size,
625                 struct rte_mempool *small_mbuf_pool,
626                 struct rte_mempool *large_mbuf_pool,
627                 uint8_t limit_segs_in_sgl,
628                 uint16_t seg_size)
629 {
630         uint32_t remaining_data = total_data_size;
631         uint16_t num_remaining_segs = DIV_CEIL(remaining_data, seg_size);
632         struct rte_mempool *pool;
633         struct rte_mbuf *next_seg;
634         uint32_t data_size;
635         char *buf_ptr;
636         const char *data_ptr = test_buf;
637         uint16_t i;
638         int ret;
639
640         if (limit_segs_in_sgl != 0 && num_remaining_segs > limit_segs_in_sgl)
641                 num_remaining_segs = limit_segs_in_sgl - 1;
642
643         /*
644          * Allocate data in the first segment (header) and
645          * copy data if test buffer is provided
646          */
647         if (remaining_data < seg_size)
648                 data_size = remaining_data;
649         else
650                 data_size = seg_size;
651         buf_ptr = rte_pktmbuf_append(head_buf, data_size);
652         if (buf_ptr == NULL) {
653                 RTE_LOG(ERR, USER1,
654                         "Not enough space in the 1st buffer\n");
655                 return -1;
656         }
657
658         if (data_ptr != NULL) {
659                 /* Copy characters without NULL terminator */
660                 strncpy(buf_ptr, data_ptr, data_size);
661                 data_ptr += data_size;
662         }
663         remaining_data -= data_size;
664         num_remaining_segs--;
665
666         /*
667          * Allocate the rest of the segments,
668          * copy the rest of the data and chain the segments.
669          */
670         for (i = 0; i < num_remaining_segs; i++) {
671
672                 if (i == (num_remaining_segs - 1)) {
673                         /* last segment */
674                         if (remaining_data > seg_size)
675                                 pool = large_mbuf_pool;
676                         else
677                                 pool = small_mbuf_pool;
678                         data_size = remaining_data;
679                 } else {
680                         data_size = seg_size;
681                         pool = small_mbuf_pool;
682                 }
683
684                 next_seg = rte_pktmbuf_alloc(pool);
685                 if (next_seg == NULL) {
686                         RTE_LOG(ERR, USER1,
687                                 "New segment could not be allocated "
688                                 "from the mempool\n");
689                         return -1;
690                 }
691                 buf_ptr = rte_pktmbuf_append(next_seg, data_size);
692                 if (buf_ptr == NULL) {
693                         RTE_LOG(ERR, USER1,
694                                 "Not enough space in the buffer\n");
695                         rte_pktmbuf_free(next_seg);
696                         return -1;
697                 }
698                 if (data_ptr != NULL) {
699                         /* Copy characters without NULL terminator */
700                         strncpy(buf_ptr, data_ptr, data_size);
701                         data_ptr += data_size;
702                 }
703                 remaining_data -= data_size;
704
705                 ret = rte_pktmbuf_chain(head_buf, next_seg);
706                 if (ret != 0) {
707                         rte_pktmbuf_free(next_seg);
708                         RTE_LOG(ERR, USER1,
709                                 "Segment could not chained\n");
710                         return -1;
711                 }
712         }
713
714         return 0;
715 }
716
717 /*
718  * Compresses and decompresses buffer with compressdev API and Zlib API
719  */
720 static int
721 test_deflate_comp_decomp(const struct interim_data_params *int_data,
722                 const struct test_data_params *test_data)
723 {
724         struct comp_testsuite_params *ts_params = &testsuite_params;
725         const char * const *test_bufs = int_data->test_bufs;
726         unsigned int num_bufs = int_data->num_bufs;
727         uint16_t *buf_idx = int_data->buf_idx;
728         struct rte_comp_xform **compress_xforms = int_data->compress_xforms;
729         struct rte_comp_xform **decompress_xforms = int_data->decompress_xforms;
730         unsigned int num_xforms = int_data->num_xforms;
731         enum rte_comp_op_type compress_state = test_data->compress_state;
732         enum rte_comp_op_type decompress_state = test_data->decompress_state;
733         unsigned int buff_type = test_data->buff_type;
734         unsigned int out_of_space = test_data->out_of_space;
735         unsigned int big_data = test_data->big_data;
736         enum zlib_direction zlib_dir = test_data->zlib_dir;
737         int ret_status = TEST_FAILED;
738         int ret;
739         struct rte_mbuf *uncomp_bufs[num_bufs];
740         struct rte_mbuf *comp_bufs[num_bufs];
741         struct rte_comp_op *ops[num_bufs];
742         struct rte_comp_op *ops_processed[num_bufs];
743         void *priv_xforms[num_bufs];
744         uint16_t num_enqd, num_deqd, num_total_deqd;
745         uint16_t num_priv_xforms = 0;
746         unsigned int deqd_retries = 0;
747         struct priv_op_data *priv_data;
748         char *buf_ptr;
749         unsigned int i;
750         struct rte_mempool *buf_pool;
751         uint32_t data_size;
752         /* Compressing with CompressDev */
753         unsigned int oos_zlib_decompress =
754                         (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_DECOMPRESS);
755         /* Decompressing with CompressDev */
756         unsigned int oos_zlib_compress =
757                         (zlib_dir == ZLIB_NONE || zlib_dir == ZLIB_COMPRESS);
758         const struct rte_compressdev_capabilities *capa =
759                 rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
760         char *contig_buf = NULL;
761         uint64_t compress_checksum[num_bufs];
762         void *stream = NULL;
763         char *all_decomp_data = NULL;
764         unsigned int decomp_produced_data_size = 0;
765         unsigned int step = 0;
766
767         TEST_ASSERT(decompress_state == RTE_COMP_OP_STATELESS || num_bufs == 1,
768                     "Number of stateful operations in a step should be 1");
769
770         if (capa == NULL) {
771                 RTE_LOG(ERR, USER1,
772                         "Compress device does not support DEFLATE\n");
773                 return -ENOTSUP;
774         }
775
776         /* Initialize all arrays to NULL */
777         memset(uncomp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs);
778         memset(comp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs);
779         memset(ops, 0, sizeof(struct rte_comp_op *) * num_bufs);
780         memset(ops_processed, 0, sizeof(struct rte_comp_op *) * num_bufs);
781         memset(priv_xforms, 0, sizeof(void *) * num_bufs);
782
783         if (decompress_state == RTE_COMP_OP_STATEFUL) {
784                 data_size = strlen(test_bufs[0]) + 1;
785                 all_decomp_data = rte_malloc(NULL, data_size,
786                                              RTE_CACHE_LINE_SIZE);
787         }
788
789         if (big_data)
790                 buf_pool = ts_params->big_mbuf_pool;
791         else if (buff_type == SGL_BOTH)
792                 buf_pool = ts_params->small_mbuf_pool;
793         else
794                 buf_pool = ts_params->large_mbuf_pool;
795
796         /* Prepare the source mbufs with the data */
797         ret = rte_pktmbuf_alloc_bulk(buf_pool,
798                                 uncomp_bufs, num_bufs);
799         if (ret < 0) {
800                 RTE_LOG(ERR, USER1,
801                         "Source mbufs could not be allocated "
802                         "from the mempool\n");
803                 goto exit;
804         }
805
806         if (buff_type == SGL_BOTH || buff_type == SGL_TO_LB) {
807                 for (i = 0; i < num_bufs; i++) {
808                         data_size = strlen(test_bufs[i]) + 1;
809                         if (prepare_sgl_bufs(test_bufs[i], uncomp_bufs[i],
810                             data_size,
811                             big_data ? buf_pool : ts_params->small_mbuf_pool,
812                             big_data ? buf_pool : ts_params->large_mbuf_pool,
813                             big_data ? 0 : MAX_SEGS,
814                             big_data ? MAX_DATA_MBUF_SIZE : SMALL_SEG_SIZE) < 0)
815                                 goto exit;
816                 }
817         } else {
818                 for (i = 0; i < num_bufs; i++) {
819                         data_size = strlen(test_bufs[i]) + 1;
820                         buf_ptr = rte_pktmbuf_append(uncomp_bufs[i], data_size);
821                         strlcpy(buf_ptr, test_bufs[i], data_size);
822                 }
823         }
824
825         /* Prepare the destination mbufs */
826         ret = rte_pktmbuf_alloc_bulk(buf_pool, comp_bufs, num_bufs);
827         if (ret < 0) {
828                 RTE_LOG(ERR, USER1,
829                         "Destination mbufs could not be allocated "
830                         "from the mempool\n");
831                 goto exit;
832         }
833
834         if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) {
835                 for (i = 0; i < num_bufs; i++) {
836                         if (out_of_space == 1 && oos_zlib_decompress)
837                                 data_size = OUT_OF_SPACE_BUF;
838                         else
839                                 (data_size = strlen(test_bufs[i]) *
840                                         COMPRESS_BUF_SIZE_RATIO);
841
842                         if (prepare_sgl_bufs(NULL, comp_bufs[i],
843                               data_size,
844                               big_data ? buf_pool : ts_params->small_mbuf_pool,
845                               big_data ? buf_pool : ts_params->large_mbuf_pool,
846                               big_data ? 0 : MAX_SEGS,
847                               big_data ? MAX_DATA_MBUF_SIZE : SMALL_SEG_SIZE)
848                                         < 0)
849                                 goto exit;
850                 }
851
852         } else {
853                 for (i = 0; i < num_bufs; i++) {
854                         if (out_of_space == 1 && oos_zlib_decompress)
855                                 data_size = OUT_OF_SPACE_BUF;
856                         else
857                                 (data_size = strlen(test_bufs[i]) *
858                                         COMPRESS_BUF_SIZE_RATIO);
859
860                         rte_pktmbuf_append(comp_bufs[i], data_size);
861                 }
862         }
863
864         /* Build the compression operations */
865         ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs);
866         if (ret < 0) {
867                 RTE_LOG(ERR, USER1,
868                         "Compress operations could not be allocated "
869                         "from the mempool\n");
870                 goto exit;
871         }
872
873
874         for (i = 0; i < num_bufs; i++) {
875                 ops[i]->m_src = uncomp_bufs[i];
876                 ops[i]->m_dst = comp_bufs[i];
877                 ops[i]->src.offset = 0;
878                 ops[i]->src.length = rte_pktmbuf_pkt_len(uncomp_bufs[i]);
879                 ops[i]->dst.offset = 0;
880                 if (compress_state == RTE_COMP_OP_STATELESS)
881                         ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL;
882                 else {
883                         RTE_LOG(ERR, USER1,
884                                 "Stateful operations are not supported "
885                                 "in these tests yet\n");
886                         goto exit;
887                 }
888                 ops[i]->input_chksum = 0;
889                 /*
890                  * Store original operation index in private data,
891                  * since ordering does not have to be maintained,
892                  * when dequeueing from compressdev, so a comparison
893                  * at the end of the test can be done.
894                  */
895                 priv_data = (struct priv_op_data *) (ops[i] + 1);
896                 priv_data->orig_idx = i;
897         }
898
899         /* Compress data (either with Zlib API or compressdev API */
900         if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) {
901                 for (i = 0; i < num_bufs; i++) {
902                         const struct rte_comp_xform *compress_xform =
903                                 compress_xforms[i % num_xforms];
904                         ret = compress_zlib(ops[i], compress_xform,
905                                         DEFAULT_MEM_LEVEL);
906                         if (ret < 0)
907                                 goto exit;
908
909                         ops_processed[i] = ops[i];
910                 }
911         } else {
912                 /* Create compress private xform data */
913                 for (i = 0; i < num_xforms; i++) {
914                         ret = rte_compressdev_private_xform_create(0,
915                                 (const struct rte_comp_xform *)compress_xforms[i],
916                                 &priv_xforms[i]);
917                         if (ret < 0) {
918                                 RTE_LOG(ERR, USER1,
919                                         "Compression private xform "
920                                         "could not be created\n");
921                                 goto exit;
922                         }
923                         num_priv_xforms++;
924                 }
925
926                 if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
927                         /* Attach shareable private xform data to ops */
928                         for (i = 0; i < num_bufs; i++)
929                                 ops[i]->private_xform = priv_xforms[i % num_xforms];
930                 } else {
931                         /* Create rest of the private xforms for the other ops */
932                         for (i = num_xforms; i < num_bufs; i++) {
933                                 ret = rte_compressdev_private_xform_create(0,
934                                         compress_xforms[i % num_xforms],
935                                         &priv_xforms[i]);
936                                 if (ret < 0) {
937                                         RTE_LOG(ERR, USER1,
938                                                 "Compression private xform "
939                                                 "could not be created\n");
940                                         goto exit;
941                                 }
942                                 num_priv_xforms++;
943                         }
944
945                         /* Attach non shareable private xform data to ops */
946                         for (i = 0; i < num_bufs; i++)
947                                 ops[i]->private_xform = priv_xforms[i];
948                 }
949
950                 /* Enqueue and dequeue all operations */
951                 num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs);
952                 if (num_enqd < num_bufs) {
953                         RTE_LOG(ERR, USER1,
954                                 "The operations could not be enqueued\n");
955                         goto exit;
956                 }
957
958                 num_total_deqd = 0;
959                 do {
960                         /*
961                          * If retrying a dequeue call, wait for 10 ms to allow
962                          * enough time to the driver to process the operations
963                          */
964                         if (deqd_retries != 0) {
965                                 /*
966                                  * Avoid infinite loop if not all the
967                                  * operations get out of the device
968                                  */
969                                 if (deqd_retries == MAX_DEQD_RETRIES) {
970                                         RTE_LOG(ERR, USER1,
971                                                 "Not all operations could be "
972                                                 "dequeued\n");
973                                         goto exit;
974                                 }
975                                 usleep(DEQUEUE_WAIT_TIME);
976                         }
977                         num_deqd = rte_compressdev_dequeue_burst(0, 0,
978                                         &ops_processed[num_total_deqd], num_bufs);
979                         num_total_deqd += num_deqd;
980                         deqd_retries++;
981
982                 } while (num_total_deqd < num_enqd);
983
984                 deqd_retries = 0;
985
986                 /* Free compress private xforms */
987                 for (i = 0; i < num_priv_xforms; i++) {
988                         rte_compressdev_private_xform_free(0, priv_xforms[i]);
989                         priv_xforms[i] = NULL;
990                 }
991                 num_priv_xforms = 0;
992         }
993
994         for (i = 0; i < num_bufs; i++) {
995                 priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
996                 uint16_t xform_idx = priv_data->orig_idx % num_xforms;
997                 const struct rte_comp_compress_xform *compress_xform =
998                                 &compress_xforms[xform_idx]->compress;
999                 enum rte_comp_huffman huffman_type =
1000                         compress_xform->deflate.huffman;
1001                 char engine[] = "zlib (directly, not PMD)";
1002                 if (zlib_dir != ZLIB_COMPRESS && zlib_dir != ZLIB_ALL)
1003                         strlcpy(engine, "PMD", sizeof(engine));
1004
1005                 RTE_LOG(DEBUG, USER1, "Buffer %u compressed by %s from %u to"
1006                         " %u bytes (level = %d, huffman = %s)\n",
1007                         buf_idx[priv_data->orig_idx], engine,
1008                         ops_processed[i]->consumed, ops_processed[i]->produced,
1009                         compress_xform->level,
1010                         huffman_type_strings[huffman_type]);
1011                 RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f\n",
1012                         ops_processed[i]->consumed == 0 ? 0 :
1013                         (float)ops_processed[i]->produced /
1014                         ops_processed[i]->consumed * 100);
1015                 if (compress_xform->chksum != RTE_COMP_CHECKSUM_NONE)
1016                         compress_checksum[i] = ops_processed[i]->output_chksum;
1017                 ops[i] = NULL;
1018         }
1019
1020         /*
1021          * Check operation status and free source mbufs (destination mbuf and
1022          * compress operation information is needed for the decompression stage)
1023          */
1024         for (i = 0; i < num_bufs; i++) {
1025                 if (out_of_space && oos_zlib_decompress) {
1026                         if (ops_processed[i]->status !=
1027                                         RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) {
1028                                 ret_status = TEST_FAILED;
1029                                 RTE_LOG(ERR, USER1,
1030                                         "Operation without expected out of "
1031                                         "space status error\n");
1032                                 goto exit;
1033                         } else
1034                                 continue;
1035                 }
1036
1037                 if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) {
1038                         RTE_LOG(ERR, USER1,
1039                                 "Some operations were not successful\n");
1040                         goto exit;
1041                 }
1042                 priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
1043                 rte_pktmbuf_free(uncomp_bufs[priv_data->orig_idx]);
1044                 uncomp_bufs[priv_data->orig_idx] = NULL;
1045         }
1046
1047         if (out_of_space && oos_zlib_decompress) {
1048                 ret_status = TEST_SUCCESS;
1049                 goto exit;
1050         }
1051
1052         /* Allocate buffers for decompressed data */
1053         ret = rte_pktmbuf_alloc_bulk(buf_pool, uncomp_bufs, num_bufs);
1054         if (ret < 0) {
1055                 RTE_LOG(ERR, USER1,
1056                         "Destination mbufs could not be allocated "
1057                         "from the mempool\n");
1058                 goto exit;
1059         }
1060
1061         if (buff_type == SGL_BOTH || buff_type == LB_TO_SGL) {
1062                 for (i = 0; i < num_bufs; i++) {
1063                         priv_data = (struct priv_op_data *)
1064                                         (ops_processed[i] + 1);
1065                         if (out_of_space == 1 && oos_zlib_compress)
1066                                 data_size = OUT_OF_SPACE_BUF;
1067                         else if (test_data->decompress_output_block_size != 0)
1068                                 data_size =
1069                                         test_data->decompress_output_block_size;
1070                         else
1071                                 data_size =
1072                                 strlen(test_bufs[priv_data->orig_idx]) + 1;
1073
1074                         if (prepare_sgl_bufs(NULL, uncomp_bufs[i],
1075                                data_size,
1076                                big_data ? buf_pool : ts_params->small_mbuf_pool,
1077                                big_data ? buf_pool : ts_params->large_mbuf_pool,
1078                                big_data ? 0 : MAX_SEGS,
1079                                big_data ? MAX_DATA_MBUF_SIZE : SMALL_SEG_SIZE)
1080                                         < 0)
1081                                 goto exit;
1082                 }
1083
1084         } else {
1085                 for (i = 0; i < num_bufs; i++) {
1086                         priv_data = (struct priv_op_data *)
1087                                         (ops_processed[i] + 1);
1088                         if (out_of_space == 1 && oos_zlib_compress)
1089                                 data_size = OUT_OF_SPACE_BUF;
1090                         else if (test_data->decompress_output_block_size != 0)
1091                                 data_size =
1092                                         test_data->decompress_output_block_size;
1093                         else
1094                                 data_size =
1095                                 strlen(test_bufs[priv_data->orig_idx]) + 1;
1096
1097                         rte_pktmbuf_append(uncomp_bufs[i], data_size);
1098                 }
1099         }
1100
1101         /* Build the decompression operations */
1102         ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs);
1103         if (ret < 0) {
1104                 RTE_LOG(ERR, USER1,
1105                         "Decompress operations could not be allocated "
1106                         "from the mempool\n");
1107                 goto exit;
1108         }
1109
1110         /* Source buffer is the compressed data from the previous operations */
1111         for (i = 0; i < num_bufs; i++) {
1112                 ops[i]->m_src = ops_processed[i]->m_dst;
1113                 ops[i]->m_dst = uncomp_bufs[i];
1114                 ops[i]->src.offset = 0;
1115                 /*
1116                  * Set the length of the compressed data to the
1117                  * number of bytes that were produced in the previous stage
1118                  */
1119                 ops[i]->src.length = ops_processed[i]->produced;
1120
1121                 ops[i]->dst.offset = 0;
1122                 if (decompress_state == RTE_COMP_OP_STATELESS) {
1123                         ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL;
1124                         ops[i]->op_type = RTE_COMP_OP_STATELESS;
1125                 } else if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_NONE) {
1126                         ops[i]->flush_flag = RTE_COMP_FLUSH_SYNC;
1127                         ops[i]->op_type = RTE_COMP_OP_STATEFUL;
1128                 } else {
1129                         RTE_LOG(ERR, USER1,
1130                                 "Stateful operations are not supported "
1131                                 "in these tests yet\n");
1132                         goto exit;
1133                 }
1134                 ops[i]->input_chksum = 0;
1135                 /*
1136                  * Copy private data from previous operations,
1137                  * to keep the pointer to the original buffer
1138                  */
1139                 memcpy(ops[i] + 1, ops_processed[i] + 1,
1140                                 sizeof(struct priv_op_data));
1141         }
1142
1143         /*
1144          * Free the previous compress operations,
1145          * as they are not needed anymore
1146          */
1147         rte_comp_op_bulk_free(ops_processed, num_bufs);
1148
1149         /* Decompress data (either with Zlib API or compressdev API */
1150         if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) {
1151                 for (i = 0; i < num_bufs; i++) {
1152                         priv_data = (struct priv_op_data *)(ops[i] + 1);
1153                         uint16_t xform_idx = priv_data->orig_idx % num_xforms;
1154                         const struct rte_comp_xform *decompress_xform =
1155                                 decompress_xforms[xform_idx];
1156
1157                         ret = decompress_zlib(ops[i], decompress_xform);
1158                         if (ret < 0)
1159                                 goto exit;
1160
1161                         ops_processed[i] = ops[i];
1162                 }
1163         } else {
1164                 if (decompress_state == RTE_COMP_OP_STATELESS) {
1165                         /* Create decompress private xform data */
1166                         for (i = 0; i < num_xforms; i++) {
1167                                 ret = rte_compressdev_private_xform_create(0,
1168                                         (const struct rte_comp_xform *)
1169                                         decompress_xforms[i],
1170                                         &priv_xforms[i]);
1171                                 if (ret < 0) {
1172                                         RTE_LOG(ERR, USER1,
1173                                                 "Decompression private xform "
1174                                                 "could not be created\n");
1175                                         goto exit;
1176                                 }
1177                                 num_priv_xforms++;
1178                         }
1179
1180                         if (capa->comp_feature_flags &
1181                                         RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
1182                                 /* Attach shareable private xform data to ops */
1183                                 for (i = 0; i < num_bufs; i++) {
1184                                         priv_data = (struct priv_op_data *)
1185                                                         (ops[i] + 1);
1186                                         uint16_t xform_idx =
1187                                                priv_data->orig_idx % num_xforms;
1188                                         ops[i]->private_xform =
1189                                                         priv_xforms[xform_idx];
1190                                 }
1191                         } else {
1192                                 /* Create rest of the private xforms */
1193                                 /* for the other ops */
1194                                 for (i = num_xforms; i < num_bufs; i++) {
1195                                         ret =
1196                                          rte_compressdev_private_xform_create(0,
1197                                               decompress_xforms[i % num_xforms],
1198                                               &priv_xforms[i]);
1199                                         if (ret < 0) {
1200                                                 RTE_LOG(ERR, USER1,
1201                                                         "Decompression private xform could not be created\n");
1202                                                 goto exit;
1203                                         }
1204                                         num_priv_xforms++;
1205                                 }
1206
1207                                 /* Attach non shareable private xform data */
1208                                 /* to ops */
1209                                 for (i = 0; i < num_bufs; i++) {
1210                                         priv_data = (struct priv_op_data *)
1211                                                         (ops[i] + 1);
1212                                         uint16_t xform_idx =
1213                                                         priv_data->orig_idx;
1214                                         ops[i]->private_xform =
1215                                                         priv_xforms[xform_idx];
1216                                 }
1217                         }
1218                 } else {
1219                         /* Create a stream object for stateful decompression */
1220                         ret = rte_compressdev_stream_create(0,
1221                                         decompress_xforms[0], &stream);
1222                         if (ret < 0) {
1223                                 RTE_LOG(ERR, USER1,
1224                                         "Decompression stream could not be created, error %d\n",
1225                                         ret);
1226                                 goto exit;
1227                         }
1228                         /* Attach stream to ops */
1229                         for (i = 0; i < num_bufs; i++)
1230                                 ops[i]->stream = stream;
1231                 }
1232
1233 next_step:
1234                 /* Enqueue and dequeue all operations */
1235                 num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs);
1236                 if (num_enqd < num_bufs) {
1237                         RTE_LOG(ERR, USER1,
1238                                 "The operations could not be enqueued\n");
1239                         goto exit;
1240                 }
1241
1242                 num_total_deqd = 0;
1243                 do {
1244                         /*
1245                          * If retrying a dequeue call, wait for 10 ms to allow
1246                          * enough time to the driver to process the operations
1247                          */
1248                         if (deqd_retries != 0) {
1249                                 /*
1250                                  * Avoid infinite loop if not all the
1251                                  * operations get out of the device
1252                                  */
1253                                 if (deqd_retries == MAX_DEQD_RETRIES) {
1254                                         RTE_LOG(ERR, USER1,
1255                                                 "Not all operations could be "
1256                                                 "dequeued\n");
1257                                         goto exit;
1258                                 }
1259                                 usleep(DEQUEUE_WAIT_TIME);
1260                         }
1261                         num_deqd = rte_compressdev_dequeue_burst(0, 0,
1262                                         &ops_processed[num_total_deqd], num_bufs);
1263                         num_total_deqd += num_deqd;
1264                         deqd_retries++;
1265                 } while (num_total_deqd < num_enqd);
1266
1267                 deqd_retries = 0;
1268         }
1269
1270         for (i = 0; i < num_bufs; i++) {
1271                 priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
1272                 char engine[] = "zlib, (directly, no PMD)";
1273                 if (zlib_dir != ZLIB_DECOMPRESS && zlib_dir != ZLIB_ALL)
1274                         strlcpy(engine, "pmd", sizeof(engine));
1275                 RTE_LOG(DEBUG, USER1,
1276                         "Buffer %u decompressed by %s from %u to %u bytes\n",
1277                         buf_idx[priv_data->orig_idx], engine,
1278                         ops_processed[i]->consumed, ops_processed[i]->produced);
1279                 ops[i] = NULL;
1280         }
1281
1282         /*
1283          * Check operation status and free source mbuf (destination mbuf and
1284          * compress operation information is still needed)
1285          */
1286         for (i = 0; i < num_bufs; i++) {
1287                 if (out_of_space && oos_zlib_compress) {
1288                         if (ops_processed[i]->status !=
1289                                         RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED) {
1290                                 ret_status = TEST_FAILED;
1291                                 RTE_LOG(ERR, USER1,
1292                                         "Operation without expected out of "
1293                                         "space status error\n");
1294                                 goto exit;
1295                         } else
1296                                 continue;
1297                 }
1298
1299                 if (decompress_state == RTE_COMP_OP_STATEFUL
1300                         && (ops_processed[i]->status ==
1301                                 RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE
1302                             || ops_processed[i]->status ==
1303                                 RTE_COMP_OP_STATUS_SUCCESS)) {
1304                         /* collect the output into all_decomp_data */
1305                         const void *ptr = rte_pktmbuf_read(
1306                                         ops_processed[i]->m_dst,
1307                                         ops_processed[i]->dst.offset,
1308                                         ops_processed[i]->produced,
1309                                         all_decomp_data +
1310                                                 decomp_produced_data_size);
1311                         if (ptr != all_decomp_data + decomp_produced_data_size)
1312                                 rte_memcpy(all_decomp_data +
1313                                            decomp_produced_data_size,
1314                                            ptr, ops_processed[i]->produced);
1315                         decomp_produced_data_size += ops_processed[i]->produced;
1316                         if (ops_processed[i]->src.length >
1317                                         ops_processed[i]->consumed) {
1318                                 if (ops_processed[i]->status ==
1319                                                 RTE_COMP_OP_STATUS_SUCCESS) {
1320                                         ret_status = -1;
1321                                         RTE_LOG(ERR, USER1,
1322                                               "Operation finished too early\n");
1323                                         goto exit;
1324                                 }
1325                                 step++;
1326                                 if (step >= test_data->decompress_steps_max) {
1327                                         ret_status = -1;
1328                                         RTE_LOG(ERR, USER1,
1329                                           "Operation exceeded maximum steps\n");
1330                                         goto exit;
1331                                 }
1332                                 ops[i] = ops_processed[i];
1333                                 ops[i]->status =
1334                                                RTE_COMP_OP_STATUS_NOT_PROCESSED;
1335                                 ops[i]->src.offset +=
1336                                                 ops_processed[i]->consumed;
1337                                 ops[i]->src.length -=
1338                                                 ops_processed[i]->consumed;
1339                                 goto next_step;
1340                         } else {
1341                                 /* Compare the original stream with the */
1342                                 /* decompressed stream (in size and the data) */
1343                                 priv_data = (struct priv_op_data *)
1344                                                 (ops_processed[i] + 1);
1345                                 const char *buf1 =
1346                                                 test_bufs[priv_data->orig_idx];
1347                                 const char *buf2 = all_decomp_data;
1348
1349                                 if (compare_buffers(buf1, strlen(buf1) + 1,
1350                                           buf2, decomp_produced_data_size) < 0)
1351                                         goto exit;
1352                                 /* Test checksums */
1353                                 if (compress_xforms[0]->compress.chksum
1354                                                 != RTE_COMP_CHECKSUM_NONE) {
1355                                         if (ops_processed[i]->output_chksum
1356                                                       != compress_checksum[i]) {
1357                                                 RTE_LOG(ERR, USER1,
1358                                                         "The checksums differ\n"
1359                              "Compression Checksum: %" PRIu64 "\tDecompression "
1360                                 "Checksum: %" PRIu64 "\n", compress_checksum[i],
1361                                                ops_processed[i]->output_chksum);
1362                                                 goto exit;
1363                                         }
1364                                 }
1365                         }
1366                 } else if (ops_processed[i]->status !=
1367                            RTE_COMP_OP_STATUS_SUCCESS) {
1368                         RTE_LOG(ERR, USER1,
1369                                 "Some operations were not successful\n");
1370                         goto exit;
1371                 }
1372                 priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
1373                 rte_pktmbuf_free(comp_bufs[priv_data->orig_idx]);
1374                 comp_bufs[priv_data->orig_idx] = NULL;
1375         }
1376
1377         if ((out_of_space && oos_zlib_compress)
1378                         || (decompress_state == RTE_COMP_OP_STATEFUL)) {
1379                 ret_status = TEST_SUCCESS;
1380                 goto exit;
1381         }
1382
1383         /*
1384          * Compare the original stream with the decompressed stream
1385          * (in size and the data)
1386          */
1387         for (i = 0; i < num_bufs; i++) {
1388                 priv_data = (struct priv_op_data *)(ops_processed[i] + 1);
1389                 const char *buf1 = test_bufs[priv_data->orig_idx];
1390                 const char *buf2;
1391                 contig_buf = rte_malloc(NULL, ops_processed[i]->produced, 0);
1392                 if (contig_buf == NULL) {
1393                         RTE_LOG(ERR, USER1, "Contiguous buffer could not "
1394                                         "be allocated\n");
1395                         goto exit;
1396                 }
1397
1398                 buf2 = rte_pktmbuf_read(ops_processed[i]->m_dst, 0,
1399                                 ops_processed[i]->produced, contig_buf);
1400                 if (compare_buffers(buf1, strlen(buf1) + 1,
1401                                 buf2, ops_processed[i]->produced) < 0)
1402                         goto exit;
1403
1404                 /* Test checksums */
1405                 if (compress_xforms[0]->compress.chksum !=
1406                                 RTE_COMP_CHECKSUM_NONE) {
1407                         if (ops_processed[i]->output_chksum !=
1408                                         compress_checksum[i]) {
1409                                 RTE_LOG(ERR, USER1, "The checksums differ\n"
1410                         "Compression Checksum: %" PRIu64 "\tDecompression "
1411                         "Checksum: %" PRIu64 "\n", compress_checksum[i],
1412                         ops_processed[i]->output_chksum);
1413                                 goto exit;
1414                         }
1415                 }
1416
1417                 rte_free(contig_buf);
1418                 contig_buf = NULL;
1419         }
1420
1421         ret_status = TEST_SUCCESS;
1422
1423 exit:
1424         /* Free resources */
1425         for (i = 0; i < num_bufs; i++) {
1426                 rte_pktmbuf_free(uncomp_bufs[i]);
1427                 rte_pktmbuf_free(comp_bufs[i]);
1428                 rte_comp_op_free(ops[i]);
1429                 rte_comp_op_free(ops_processed[i]);
1430         }
1431         for (i = 0; i < num_priv_xforms; i++)
1432                 if (priv_xforms[i] != NULL)
1433                         rte_compressdev_private_xform_free(0, priv_xforms[i]);
1434         if (stream != NULL)
1435                 rte_compressdev_stream_free(0, stream);
1436         if (all_decomp_data != NULL)
1437                 rte_free(all_decomp_data);
1438         rte_free(contig_buf);
1439
1440         return ret_status;
1441 }
1442
1443 static int
1444 test_compressdev_deflate_stateless_fixed(void)
1445 {
1446         struct comp_testsuite_params *ts_params = &testsuite_params;
1447         uint16_t i;
1448         int ret;
1449         const struct rte_compressdev_capabilities *capab;
1450
1451         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
1452         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
1453
1454         if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0)
1455                 return -ENOTSUP;
1456
1457         struct rte_comp_xform *compress_xform =
1458                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
1459
1460         if (compress_xform == NULL) {
1461                 RTE_LOG(ERR, USER1,
1462                         "Compress xform could not be created\n");
1463                 ret = TEST_FAILED;
1464                 goto exit;
1465         }
1466
1467         memcpy(compress_xform, ts_params->def_comp_xform,
1468                         sizeof(struct rte_comp_xform));
1469         compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED;
1470
1471         struct interim_data_params int_data = {
1472                 NULL,
1473                 1,
1474                 NULL,
1475                 &compress_xform,
1476                 &ts_params->def_decomp_xform,
1477                 1
1478         };
1479
1480         struct test_data_params test_data = {
1481                 RTE_COMP_OP_STATELESS,
1482                 RTE_COMP_OP_STATELESS,
1483                 LB_BOTH,
1484                 ZLIB_DECOMPRESS,
1485                 0,
1486                 0,
1487                 0,
1488                 0
1489         };
1490
1491         for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1492                 int_data.test_bufs = &compress_test_bufs[i];
1493                 int_data.buf_idx = &i;
1494
1495                 /* Compress with compressdev, decompress with Zlib */
1496                 test_data.zlib_dir = ZLIB_DECOMPRESS;
1497                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1498                 if (ret < 0)
1499                         goto exit;
1500
1501                 /* Compress with Zlib, decompress with compressdev */
1502                 test_data.zlib_dir = ZLIB_COMPRESS;
1503                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1504                 if (ret < 0)
1505                         goto exit;
1506         }
1507
1508         ret = TEST_SUCCESS;
1509
1510 exit:
1511         rte_free(compress_xform);
1512         return ret;
1513 }
1514
1515 static int
1516 test_compressdev_deflate_stateless_dynamic(void)
1517 {
1518         struct comp_testsuite_params *ts_params = &testsuite_params;
1519         uint16_t i;
1520         int ret;
1521         struct rte_comp_xform *compress_xform =
1522                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
1523
1524         const struct rte_compressdev_capabilities *capab;
1525
1526         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
1527         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
1528
1529         if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_DYNAMIC) == 0)
1530                 return -ENOTSUP;
1531
1532         if (compress_xform == NULL) {
1533                 RTE_LOG(ERR, USER1,
1534                         "Compress xform could not be created\n");
1535                 ret = TEST_FAILED;
1536                 goto exit;
1537         }
1538
1539         memcpy(compress_xform, ts_params->def_comp_xform,
1540                         sizeof(struct rte_comp_xform));
1541         compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC;
1542
1543         struct interim_data_params int_data = {
1544                 NULL,
1545                 1,
1546                 NULL,
1547                 &compress_xform,
1548                 &ts_params->def_decomp_xform,
1549                 1
1550         };
1551
1552         struct test_data_params test_data = {
1553                 RTE_COMP_OP_STATELESS,
1554                 RTE_COMP_OP_STATELESS,
1555                 LB_BOTH,
1556                 ZLIB_DECOMPRESS,
1557                 0,
1558                 0,
1559                 0,
1560                 0
1561         };
1562
1563         for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1564                 int_data.test_bufs = &compress_test_bufs[i];
1565                 int_data.buf_idx = &i;
1566
1567                 /* Compress with compressdev, decompress with Zlib */
1568                 test_data.zlib_dir = ZLIB_DECOMPRESS;
1569                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1570                 if (ret < 0)
1571                         goto exit;
1572
1573                 /* Compress with Zlib, decompress with compressdev */
1574                 test_data.zlib_dir = ZLIB_COMPRESS;
1575                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1576                 if (ret < 0)
1577                         goto exit;
1578         }
1579
1580         ret = TEST_SUCCESS;
1581
1582 exit:
1583         rte_free(compress_xform);
1584         return ret;
1585 }
1586
1587 static int
1588 test_compressdev_deflate_stateless_multi_op(void)
1589 {
1590         struct comp_testsuite_params *ts_params = &testsuite_params;
1591         uint16_t num_bufs = RTE_DIM(compress_test_bufs);
1592         uint16_t buf_idx[num_bufs];
1593         uint16_t i;
1594         int ret;
1595
1596         for (i = 0; i < num_bufs; i++)
1597                 buf_idx[i] = i;
1598
1599         struct interim_data_params int_data = {
1600                 compress_test_bufs,
1601                 num_bufs,
1602                 buf_idx,
1603                 &ts_params->def_comp_xform,
1604                 &ts_params->def_decomp_xform,
1605                 1
1606         };
1607
1608         struct test_data_params test_data = {
1609                 RTE_COMP_OP_STATELESS,
1610                 RTE_COMP_OP_STATELESS,
1611                 LB_BOTH,
1612                 ZLIB_DECOMPRESS,
1613                 0,
1614                 0,
1615                 0,
1616                 0
1617         };
1618
1619         /* Compress with compressdev, decompress with Zlib */
1620         test_data.zlib_dir = ZLIB_DECOMPRESS;
1621         ret = test_deflate_comp_decomp(&int_data, &test_data);
1622         if (ret < 0)
1623                 return ret;
1624
1625         /* Compress with Zlib, decompress with compressdev */
1626         test_data.zlib_dir = ZLIB_COMPRESS;
1627         ret = test_deflate_comp_decomp(&int_data, &test_data);
1628         if (ret < 0)
1629                 return ret;
1630
1631         return TEST_SUCCESS;
1632 }
1633
1634 static int
1635 test_compressdev_deflate_stateless_multi_level(void)
1636 {
1637         struct comp_testsuite_params *ts_params = &testsuite_params;
1638         unsigned int level;
1639         uint16_t i;
1640         int ret;
1641         struct rte_comp_xform *compress_xform =
1642                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
1643
1644         if (compress_xform == NULL) {
1645                 RTE_LOG(ERR, USER1,
1646                         "Compress xform could not be created\n");
1647                 ret = TEST_FAILED;
1648                 goto exit;
1649         }
1650
1651         memcpy(compress_xform, ts_params->def_comp_xform,
1652                         sizeof(struct rte_comp_xform));
1653
1654         struct interim_data_params int_data = {
1655                 NULL,
1656                 1,
1657                 NULL,
1658                 &compress_xform,
1659                 &ts_params->def_decomp_xform,
1660                 1
1661         };
1662
1663         struct test_data_params test_data = {
1664                 RTE_COMP_OP_STATELESS,
1665                 RTE_COMP_OP_STATELESS,
1666                 LB_BOTH,
1667                 ZLIB_DECOMPRESS,
1668                 0,
1669                 0,
1670                 0,
1671                 0
1672         };
1673
1674         for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1675                 int_data.test_bufs = &compress_test_bufs[i];
1676                 int_data.buf_idx = &i;
1677
1678                 for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX;
1679                                 level++) {
1680                         compress_xform->compress.level = level;
1681                         /* Compress with compressdev, decompress with Zlib */
1682                         test_data.zlib_dir = ZLIB_DECOMPRESS;
1683                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1684                         if (ret < 0)
1685                                 goto exit;
1686                 }
1687         }
1688
1689         ret = TEST_SUCCESS;
1690
1691 exit:
1692         rte_free(compress_xform);
1693         return ret;
1694 }
1695
1696 #define NUM_XFORMS 3
1697 static int
1698 test_compressdev_deflate_stateless_multi_xform(void)
1699 {
1700         struct comp_testsuite_params *ts_params = &testsuite_params;
1701         uint16_t num_bufs = NUM_XFORMS;
1702         struct rte_comp_xform *compress_xforms[NUM_XFORMS] = {NULL};
1703         struct rte_comp_xform *decompress_xforms[NUM_XFORMS] = {NULL};
1704         const char *test_buffers[NUM_XFORMS];
1705         uint16_t i;
1706         unsigned int level = RTE_COMP_LEVEL_MIN;
1707         uint16_t buf_idx[num_bufs];
1708         int ret;
1709
1710         /* Create multiple xforms with various levels */
1711         for (i = 0; i < NUM_XFORMS; i++) {
1712                 compress_xforms[i] = rte_malloc(NULL,
1713                                 sizeof(struct rte_comp_xform), 0);
1714                 if (compress_xforms[i] == NULL) {
1715                         RTE_LOG(ERR, USER1,
1716                                 "Compress xform could not be created\n");
1717                         ret = TEST_FAILED;
1718                         goto exit;
1719                 }
1720
1721                 memcpy(compress_xforms[i], ts_params->def_comp_xform,
1722                                 sizeof(struct rte_comp_xform));
1723                 compress_xforms[i]->compress.level = level;
1724                 level++;
1725
1726                 decompress_xforms[i] = rte_malloc(NULL,
1727                                 sizeof(struct rte_comp_xform), 0);
1728                 if (decompress_xforms[i] == NULL) {
1729                         RTE_LOG(ERR, USER1,
1730                                 "Decompress xform could not be created\n");
1731                         ret = TEST_FAILED;
1732                         goto exit;
1733                 }
1734
1735                 memcpy(decompress_xforms[i], ts_params->def_decomp_xform,
1736                                 sizeof(struct rte_comp_xform));
1737         }
1738
1739         for (i = 0; i < NUM_XFORMS; i++) {
1740                 buf_idx[i] = 0;
1741                 /* Use the same buffer in all sessions */
1742                 test_buffers[i] = compress_test_bufs[0];
1743         }
1744
1745         struct interim_data_params int_data = {
1746                 test_buffers,
1747                 num_bufs,
1748                 buf_idx,
1749                 compress_xforms,
1750                 decompress_xforms,
1751                 NUM_XFORMS
1752         };
1753
1754         struct test_data_params test_data = {
1755                 RTE_COMP_OP_STATELESS,
1756                 RTE_COMP_OP_STATELESS,
1757                 LB_BOTH,
1758                 ZLIB_DECOMPRESS,
1759                 0,
1760                 0,
1761                 0,
1762                 0
1763         };
1764
1765         /* Compress with compressdev, decompress with Zlib */
1766         ret = test_deflate_comp_decomp(&int_data, &test_data);
1767         if (ret < 0)
1768                 goto exit;
1769
1770         ret = TEST_SUCCESS;
1771
1772 exit:
1773         for (i = 0; i < NUM_XFORMS; i++) {
1774                 rte_free(compress_xforms[i]);
1775                 rte_free(decompress_xforms[i]);
1776         }
1777
1778         return ret;
1779 }
1780
1781 static int
1782 test_compressdev_deflate_stateless_sgl(void)
1783 {
1784         struct comp_testsuite_params *ts_params = &testsuite_params;
1785         uint16_t i;
1786         int ret;
1787         const struct rte_compressdev_capabilities *capab;
1788
1789         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
1790         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
1791
1792         if ((capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) == 0)
1793                 return -ENOTSUP;
1794
1795         struct interim_data_params int_data = {
1796                 NULL,
1797                 1,
1798                 NULL,
1799                 &ts_params->def_comp_xform,
1800                 &ts_params->def_decomp_xform,
1801                 1
1802         };
1803
1804         struct test_data_params test_data = {
1805                 RTE_COMP_OP_STATELESS,
1806                 RTE_COMP_OP_STATELESS,
1807                 SGL_BOTH,
1808                 ZLIB_DECOMPRESS,
1809                 0,
1810                 0,
1811                 0,
1812                 0
1813         };
1814
1815         for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1816                 int_data.test_bufs = &compress_test_bufs[i];
1817                 int_data.buf_idx = &i;
1818
1819                 /* Compress with compressdev, decompress with Zlib */
1820                 test_data.zlib_dir = ZLIB_DECOMPRESS;
1821                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1822                 if (ret < 0)
1823                         return ret;
1824
1825                 /* Compress with Zlib, decompress with compressdev */
1826                 test_data.zlib_dir = ZLIB_COMPRESS;
1827                 ret = test_deflate_comp_decomp(&int_data, &test_data);
1828                 if (ret < 0)
1829                         return ret;
1830
1831                 if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_LB_OUT) {
1832                         /* Compress with compressdev, decompress with Zlib */
1833                         test_data.zlib_dir = ZLIB_DECOMPRESS;
1834                         test_data.buff_type = SGL_TO_LB;
1835                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1836                         if (ret < 0)
1837                                 return ret;
1838
1839                         /* Compress with Zlib, decompress with compressdev */
1840                         test_data.zlib_dir = ZLIB_COMPRESS;
1841                         test_data.buff_type = SGL_TO_LB;
1842                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1843                         if (ret < 0)
1844                                 return ret;
1845                 }
1846
1847                 if (capab->comp_feature_flags & RTE_COMP_FF_OOP_LB_IN_SGL_OUT) {
1848                         /* Compress with compressdev, decompress with Zlib */
1849                         test_data.zlib_dir = ZLIB_DECOMPRESS;
1850                         test_data.buff_type = LB_TO_SGL;
1851                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1852                         if (ret < 0)
1853                                 return ret;
1854
1855                         /* Compress with Zlib, decompress with compressdev */
1856                         test_data.zlib_dir = ZLIB_COMPRESS;
1857                         test_data.buff_type = LB_TO_SGL;
1858                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1859                         if (ret < 0)
1860                                 return ret;
1861                 }
1862         }
1863
1864         return TEST_SUCCESS;
1865 }
1866
1867 static int
1868 test_compressdev_deflate_stateless_checksum(void)
1869 {
1870         struct comp_testsuite_params *ts_params = &testsuite_params;
1871         uint16_t i;
1872         int ret;
1873         const struct rte_compressdev_capabilities *capab;
1874
1875         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
1876         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
1877
1878         /* Check if driver supports any checksum */
1879         if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM) == 0 &&
1880                         (capab->comp_feature_flags &
1881                         RTE_COMP_FF_ADLER32_CHECKSUM) == 0 &&
1882                         (capab->comp_feature_flags &
1883                         RTE_COMP_FF_CRC32_ADLER32_CHECKSUM) == 0)
1884                 return -ENOTSUP;
1885
1886         struct rte_comp_xform *compress_xform =
1887                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
1888         if (compress_xform == NULL) {
1889                 RTE_LOG(ERR, USER1, "Compress xform could not be created\n");
1890                 return TEST_FAILED;
1891         }
1892
1893         memcpy(compress_xform, ts_params->def_comp_xform,
1894                         sizeof(struct rte_comp_xform));
1895
1896         struct rte_comp_xform *decompress_xform =
1897                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
1898         if (decompress_xform == NULL) {
1899                 RTE_LOG(ERR, USER1, "Decompress xform could not be created\n");
1900                 rte_free(compress_xform);
1901                 return TEST_FAILED;
1902         }
1903
1904         memcpy(decompress_xform, ts_params->def_decomp_xform,
1905                         sizeof(struct rte_comp_xform));
1906
1907         struct interim_data_params int_data = {
1908                 NULL,
1909                 1,
1910                 NULL,
1911                 &compress_xform,
1912                 &decompress_xform,
1913                 1
1914         };
1915
1916         struct test_data_params test_data = {
1917                 RTE_COMP_OP_STATELESS,
1918                 RTE_COMP_OP_STATELESS,
1919                 LB_BOTH,
1920                 ZLIB_DECOMPRESS,
1921                 0,
1922                 0,
1923                 0,
1924                 0
1925         };
1926
1927         /* Check if driver supports crc32 checksum and test */
1928         if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM)) {
1929                 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32;
1930                 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32;
1931
1932                 for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1933                         /* Compress with compressdev, decompress with Zlib */
1934                         int_data.test_bufs = &compress_test_bufs[i];
1935                         int_data.buf_idx = &i;
1936
1937                         /* Generate zlib checksum and test against selected
1938                          * drivers decompression checksum
1939                          */
1940                         test_data.zlib_dir = ZLIB_COMPRESS;
1941                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1942                         if (ret < 0)
1943                                 goto exit;
1944
1945                         /* Generate compression and decompression
1946                          * checksum of selected driver
1947                          */
1948                         test_data.zlib_dir = ZLIB_NONE;
1949                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1950                         if (ret < 0)
1951                                 goto exit;
1952                 }
1953         }
1954
1955         /* Check if driver supports adler32 checksum and test */
1956         if ((capab->comp_feature_flags & RTE_COMP_FF_ADLER32_CHECKSUM)) {
1957                 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32;
1958                 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32;
1959
1960                 for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1961                         int_data.test_bufs = &compress_test_bufs[i];
1962                         int_data.buf_idx = &i;
1963
1964                         /* Generate zlib checksum and test against selected
1965                          * drivers decompression checksum
1966                          */
1967                         test_data.zlib_dir = ZLIB_COMPRESS;
1968                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1969                         if (ret < 0)
1970                                 goto exit;
1971                         /* Generate compression and decompression
1972                          * checksum of selected driver
1973                          */
1974                         test_data.zlib_dir = ZLIB_NONE;
1975                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1976                         if (ret < 0)
1977                                 goto exit;
1978                 }
1979         }
1980
1981         /* Check if driver supports combined crc and adler checksum and test */
1982         if ((capab->comp_feature_flags & RTE_COMP_FF_CRC32_ADLER32_CHECKSUM)) {
1983                 compress_xform->compress.chksum =
1984                                 RTE_COMP_CHECKSUM_CRC32_ADLER32;
1985                 decompress_xform->decompress.chksum =
1986                                 RTE_COMP_CHECKSUM_CRC32_ADLER32;
1987
1988                 for (i = 0; i < RTE_DIM(compress_test_bufs); i++) {
1989                         int_data.test_bufs = &compress_test_bufs[i];
1990                         int_data.buf_idx = &i;
1991
1992                         /* Generate compression and decompression
1993                          * checksum of selected driver
1994                          */
1995                         test_data.zlib_dir = ZLIB_NONE;
1996                         ret = test_deflate_comp_decomp(&int_data, &test_data);
1997                         if (ret < 0)
1998                                 goto exit;
1999                 }
2000         }
2001
2002         ret = TEST_SUCCESS;
2003
2004 exit:
2005         rte_free(compress_xform);
2006         rte_free(decompress_xform);
2007         return ret;
2008 }
2009
2010 static int
2011 test_compressdev_out_of_space_buffer(void)
2012 {
2013         struct comp_testsuite_params *ts_params = &testsuite_params;
2014         int ret;
2015         uint16_t i;
2016         const struct rte_compressdev_capabilities *capab;
2017
2018         RTE_LOG(INFO, USER1, "This is a negative test, errors are expected\n");
2019
2020         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
2021         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
2022
2023         if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0)
2024                 return -ENOTSUP;
2025
2026         struct interim_data_params int_data = {
2027                 &compress_test_bufs[0],
2028                 1,
2029                 &i,
2030                 &ts_params->def_comp_xform,
2031                 &ts_params->def_decomp_xform,
2032                 1
2033         };
2034
2035         struct test_data_params test_data = {
2036                 RTE_COMP_OP_STATELESS,
2037                 RTE_COMP_OP_STATELESS,
2038                 LB_BOTH,
2039                 ZLIB_DECOMPRESS,
2040                 1,  /* run out-of-space test */
2041                 0,
2042                 0,
2043                 0
2044         };
2045         /* Compress with compressdev, decompress with Zlib */
2046         test_data.zlib_dir = ZLIB_DECOMPRESS;
2047         ret = test_deflate_comp_decomp(&int_data, &test_data);
2048         if (ret < 0)
2049                 goto exit;
2050
2051         /* Compress with Zlib, decompress with compressdev */
2052         test_data.zlib_dir = ZLIB_COMPRESS;
2053         ret = test_deflate_comp_decomp(&int_data, &test_data);
2054         if (ret < 0)
2055                 goto exit;
2056
2057         if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
2058                 /* Compress with compressdev, decompress with Zlib */
2059                 test_data.zlib_dir = ZLIB_DECOMPRESS;
2060                 test_data.buff_type = SGL_BOTH;
2061                 ret = test_deflate_comp_decomp(&int_data, &test_data);
2062                 if (ret < 0)
2063                         goto exit;
2064
2065                 /* Compress with Zlib, decompress with compressdev */
2066                 test_data.zlib_dir = ZLIB_COMPRESS;
2067                 test_data.buff_type = SGL_BOTH;
2068                 ret = test_deflate_comp_decomp(&int_data, &test_data);
2069                 if (ret < 0)
2070                         goto exit;
2071         }
2072
2073         ret  = TEST_SUCCESS;
2074
2075 exit:
2076         return ret;
2077 }
2078
2079 static int
2080 test_compressdev_deflate_stateless_dynamic_big(void)
2081 {
2082         struct comp_testsuite_params *ts_params = &testsuite_params;
2083         uint16_t i = 0;
2084         int ret;
2085         int j;
2086         const struct rte_compressdev_capabilities *capab;
2087         char *test_buffer = NULL;
2088
2089         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
2090         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
2091
2092         if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_DYNAMIC) == 0)
2093                 return -ENOTSUP;
2094
2095         if ((capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) == 0)
2096                 return -ENOTSUP;
2097
2098         test_buffer = rte_malloc(NULL, BIG_DATA_TEST_SIZE, 0);
2099         if (test_buffer == NULL) {
2100                 RTE_LOG(ERR, USER1,
2101                         "Can't allocate buffer for big-data\n");
2102                 return TEST_FAILED;
2103         }
2104
2105         struct interim_data_params int_data = {
2106                 (const char * const *)&test_buffer,
2107                 1,
2108                 &i,
2109                 &ts_params->def_comp_xform,
2110                 &ts_params->def_decomp_xform,
2111                 1
2112         };
2113
2114         struct test_data_params test_data = {
2115                 RTE_COMP_OP_STATELESS,
2116                 RTE_COMP_OP_STATELESS,
2117                 SGL_BOTH,
2118                 ZLIB_DECOMPRESS,
2119                 0,
2120                 1,
2121                 0,
2122                 0
2123         };
2124
2125         ts_params->def_comp_xform->compress.deflate.huffman =
2126                                                 RTE_COMP_HUFFMAN_DYNAMIC;
2127
2128         /* fill the buffer with data based on rand. data */
2129         srand(BIG_DATA_TEST_SIZE);
2130         for (j = 0; j < BIG_DATA_TEST_SIZE - 1; ++j)
2131                 test_buffer[j] = (uint8_t)(rand() % ((uint8_t)-1)) | 1;
2132         test_buffer[BIG_DATA_TEST_SIZE-1] = 0;
2133
2134         /* Compress with compressdev, decompress with Zlib */
2135         test_data.zlib_dir = ZLIB_DECOMPRESS;
2136         ret = test_deflate_comp_decomp(&int_data, &test_data);
2137         if (ret < 0)
2138                 goto exit;
2139
2140         /* Compress with Zlib, decompress with compressdev */
2141         test_data.zlib_dir = ZLIB_COMPRESS;
2142         ret = test_deflate_comp_decomp(&int_data, &test_data);
2143         if (ret < 0)
2144                 goto exit;
2145
2146         ret = TEST_SUCCESS;
2147
2148 exit:
2149         ts_params->def_comp_xform->compress.deflate.huffman =
2150                                                 RTE_COMP_HUFFMAN_DEFAULT;
2151         rte_free(test_buffer);
2152         return ret;
2153 }
2154
2155 static int
2156 test_compressdev_deflate_stateful_decomp(void)
2157 {
2158         struct comp_testsuite_params *ts_params = &testsuite_params;
2159         int ret;
2160         uint16_t i;
2161         const struct rte_compressdev_capabilities *capab;
2162
2163         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
2164         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
2165
2166         if (!(capab->comp_feature_flags & RTE_COMP_FF_STATEFUL_DECOMPRESSION))
2167                 return -ENOTSUP;
2168
2169         struct interim_data_params int_data = {
2170                 &compress_test_bufs[0],
2171                 1,
2172                 &i,
2173                 &ts_params->def_comp_xform,
2174                 &ts_params->def_decomp_xform,
2175                 1
2176         };
2177
2178         struct test_data_params test_data = {
2179                 RTE_COMP_OP_STATELESS,
2180                 RTE_COMP_OP_STATEFUL,
2181                 LB_BOTH,
2182                 ZLIB_COMPRESS,
2183                 0,
2184                 0,
2185                 2000,
2186                 4
2187         };
2188
2189         /* Compress with Zlib, decompress with compressdev */
2190         if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
2191                 ret = TEST_FAILED;
2192                 goto exit;
2193         }
2194
2195         if (capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
2196                 /* Now test with SGL buffers */
2197                 test_data.buff_type = SGL_BOTH;
2198                 if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
2199                         ret = TEST_FAILED;
2200                         goto exit;
2201                 }
2202         }
2203
2204         ret  = TEST_SUCCESS;
2205
2206 exit:
2207         return ret;
2208 }
2209
2210 static int
2211 test_compressdev_deflate_stateful_decomp_checksum(void)
2212 {
2213         struct comp_testsuite_params *ts_params = &testsuite_params;
2214         int ret;
2215         uint16_t i;
2216         const struct rte_compressdev_capabilities *capab;
2217
2218         capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);
2219         TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");
2220
2221         if (!(capab->comp_feature_flags & RTE_COMP_FF_STATEFUL_DECOMPRESSION))
2222                 return -ENOTSUP;
2223
2224         /* Check if driver supports any checksum */
2225         if (!(capab->comp_feature_flags &
2226              (RTE_COMP_FF_CRC32_CHECKSUM | RTE_COMP_FF_ADLER32_CHECKSUM |
2227               RTE_COMP_FF_CRC32_ADLER32_CHECKSUM)))
2228                 return -ENOTSUP;
2229
2230         struct rte_comp_xform *compress_xform =
2231                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
2232         if (compress_xform == NULL) {
2233                 RTE_LOG(ERR, USER1, "Compress xform could not be created\n");
2234                 return TEST_FAILED;
2235         }
2236
2237         memcpy(compress_xform, ts_params->def_comp_xform,
2238                sizeof(struct rte_comp_xform));
2239
2240         struct rte_comp_xform *decompress_xform =
2241                         rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);
2242         if (decompress_xform == NULL) {
2243                 RTE_LOG(ERR, USER1, "Decompress xform could not be created\n");
2244                 rte_free(compress_xform);
2245                 return TEST_FAILED;
2246         }
2247
2248         memcpy(decompress_xform, ts_params->def_decomp_xform,
2249                sizeof(struct rte_comp_xform));
2250
2251         struct interim_data_params int_data = {
2252                 &compress_test_bufs[0],
2253                 1,
2254                 &i,
2255                 &compress_xform,
2256                 &decompress_xform,
2257                 1
2258         };
2259
2260         struct test_data_params test_data = {
2261                 RTE_COMP_OP_STATELESS,
2262                 RTE_COMP_OP_STATEFUL,
2263                 LB_BOTH,
2264                 ZLIB_COMPRESS,
2265                 0,
2266                 0,
2267                 2000,
2268                 4
2269         };
2270
2271         /* Check if driver supports crc32 checksum and test */
2272         if (capab->comp_feature_flags & RTE_COMP_FF_CRC32_CHECKSUM) {
2273                 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32;
2274                 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32;
2275                 /* Compress with Zlib, decompress with compressdev */
2276                 test_data.buff_type = LB_BOTH;
2277                 if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
2278                         ret = TEST_FAILED;
2279                         goto exit;
2280                 }
2281                 if (capab->comp_feature_flags &
2282                                 RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
2283                         /* Now test with SGL buffers */
2284                         test_data.buff_type = SGL_BOTH;
2285                         if (test_deflate_comp_decomp(&int_data,
2286                                                      &test_data) < 0) {
2287                                 ret = TEST_FAILED;
2288                                 goto exit;
2289                         }
2290                 }
2291         }
2292
2293         /* Check if driver supports adler32 checksum and test */
2294         if (capab->comp_feature_flags & RTE_COMP_FF_ADLER32_CHECKSUM) {
2295                 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32;
2296                 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32;
2297                 /* Compress with Zlib, decompress with compressdev */
2298                 test_data.buff_type = LB_BOTH;
2299                 if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
2300                         ret = TEST_FAILED;
2301                         goto exit;
2302                 }
2303                 if (capab->comp_feature_flags &
2304                                 RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
2305                         /* Now test with SGL buffers */
2306                         test_data.buff_type = SGL_BOTH;
2307                         if (test_deflate_comp_decomp(&int_data,
2308                                                      &test_data) < 0) {
2309                                 ret = TEST_FAILED;
2310                                 goto exit;
2311                         }
2312                 }
2313         }
2314
2315         /* Check if driver supports combined crc and adler checksum and test */
2316         if (capab->comp_feature_flags & RTE_COMP_FF_CRC32_ADLER32_CHECKSUM) {
2317                 compress_xform->compress.chksum =
2318                                 RTE_COMP_CHECKSUM_CRC32_ADLER32;
2319                 decompress_xform->decompress.chksum =
2320                                 RTE_COMP_CHECKSUM_CRC32_ADLER32;
2321                 /* Zlib doesn't support combined checksum */
2322                 test_data.zlib_dir = ZLIB_NONE;
2323                 /* Compress stateless, decompress stateful with compressdev */
2324                 test_data.buff_type = LB_BOTH;
2325                 if (test_deflate_comp_decomp(&int_data, &test_data) < 0) {
2326                         ret = TEST_FAILED;
2327                         goto exit;
2328                 }
2329                 if (capab->comp_feature_flags &
2330                                 RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) {
2331                         /* Now test with SGL buffers */
2332                         test_data.buff_type = SGL_BOTH;
2333                         if (test_deflate_comp_decomp(&int_data,
2334                                                      &test_data) < 0) {
2335                                 ret = TEST_FAILED;
2336                                 goto exit;
2337                         }
2338                 }
2339         }
2340
2341         ret  = TEST_SUCCESS;
2342
2343 exit:
2344         rte_free(compress_xform);
2345         rte_free(decompress_xform);
2346         return ret;
2347 }
2348
2349 static struct unit_test_suite compressdev_testsuite  = {
2350         .suite_name = "compressdev unit test suite",
2351         .setup = testsuite_setup,
2352         .teardown = testsuite_teardown,
2353         .unit_test_cases = {
2354                 TEST_CASE_ST(NULL, NULL,
2355                         test_compressdev_invalid_configuration),
2356                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2357                         test_compressdev_deflate_stateless_fixed),
2358                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2359                         test_compressdev_deflate_stateless_dynamic),
2360                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2361                         test_compressdev_deflate_stateless_dynamic_big),
2362                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2363                         test_compressdev_deflate_stateless_multi_op),
2364                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2365                         test_compressdev_deflate_stateless_multi_level),
2366                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2367                         test_compressdev_deflate_stateless_multi_xform),
2368                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2369                         test_compressdev_deflate_stateless_sgl),
2370                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2371                         test_compressdev_deflate_stateless_checksum),
2372                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2373                         test_compressdev_out_of_space_buffer),
2374                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2375                         test_compressdev_deflate_stateful_decomp),
2376                 TEST_CASE_ST(generic_ut_setup, generic_ut_teardown,
2377                         test_compressdev_deflate_stateful_decomp_checksum),
2378                 TEST_CASES_END() /**< NULL terminate unit test array */
2379         }
2380 };
2381
2382 static int
2383 test_compressdev(void)
2384 {
2385         return unit_test_suite_runner(&compressdev_testsuite);
2386 }
2387
2388 REGISTER_TEST_COMMAND(compressdev_autotest, test_compressdev);