X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=test%2Ftest%2Ftest_compressdev.c;h=86453882afed008712779aa948e825d45a2a74d8;hb=ba7eeb035a5f442414f9dca6c12a9105a16576aa;hp=7de21ceadfafee8adb8c7587645e6939896c0980;hpb=b06aa643cac4ea815b9ae6aec6c09bf584c33bd6;p=dpdk.git diff --git a/test/test/test_compressdev.c b/test/test/test_compressdev.c index 7de21ceadf..86453882af 100644 --- a/test/test/test_compressdev.c +++ b/test/test/test_compressdev.c @@ -14,6 +14,8 @@ #include "test_compressdev_test_buffer.h" #include "test.h" +#define DIV_CEIL(a, b) ((a) / (b) + ((a) % (b) != 0)) + #define DEFAULT_WINDOW_SIZE 15 #define DEFAULT_MEM_LEVEL 8 #define MAX_DEQD_RETRIES 10 @@ -25,9 +27,11 @@ * due to the compress block headers */ #define COMPRESS_BUF_SIZE_RATIO 1.3 -#define NUM_MBUFS 16 +#define NUM_LARGE_MBUFS 16 +#define SMALL_SEG_SIZE 256 +#define MAX_SEGS 16 #define NUM_OPS 16 -#define NUM_MAX_XFORMS 1 +#define NUM_MAX_XFORMS 16 #define NUM_MAX_INFLIGHT_OPS 128 #define CACHE_SIZE 0 @@ -45,11 +49,16 @@ enum zlib_direction { ZLIB_ALL }; +struct priv_op_data { + uint16_t orig_idx; +}; + struct comp_testsuite_params { - struct rte_mempool *mbuf_pool; + struct rte_mempool *large_mbuf_pool; + struct rte_mempool *small_mbuf_pool; struct rte_mempool *op_pool; - struct rte_comp_xform def_comp_xform; - struct rte_comp_xform def_decomp_xform; + struct rte_comp_xform *def_comp_xform; + struct rte_comp_xform *def_decomp_xform; }; static struct comp_testsuite_params testsuite_params = { 0 }; @@ -59,14 +68,18 @@ testsuite_teardown(void) { struct comp_testsuite_params *ts_params = &testsuite_params; - rte_mempool_free(ts_params->mbuf_pool); + rte_mempool_free(ts_params->large_mbuf_pool); + rte_mempool_free(ts_params->small_mbuf_pool); rte_mempool_free(ts_params->op_pool); + rte_free(ts_params->def_comp_xform); + rte_free(ts_params->def_decomp_xform); } static int testsuite_setup(void) { struct comp_testsuite_params *ts_params = &testsuite_params; + uint32_t max_buf_size = 0; unsigned int i; if (rte_compressdev_count() == 0) { @@ -74,48 +87,77 @@ testsuite_setup(void) return TEST_FAILED; } - uint32_t max_buf_size = 0; + RTE_LOG(NOTICE, USER1, "Running tests on device %s\n", + rte_compressdev_name_get(0)); + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) max_buf_size = RTE_MAX(max_buf_size, strlen(compress_test_bufs[i]) + 1); - max_buf_size *= COMPRESS_BUF_SIZE_RATIO; /* * Buffers to be used in compression and decompression. * Since decompressed data might be larger than * compressed data (due to block header), * buffers should be big enough for both cases. */ - ts_params->mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", - NUM_MBUFS, + max_buf_size *= COMPRESS_BUF_SIZE_RATIO; + ts_params->large_mbuf_pool = rte_pktmbuf_pool_create("large_mbuf_pool", + NUM_LARGE_MBUFS, CACHE_SIZE, 0, max_buf_size + RTE_PKTMBUF_HEADROOM, rte_socket_id()); - if (ts_params->mbuf_pool == NULL) { + if (ts_params->large_mbuf_pool == NULL) { RTE_LOG(ERR, USER1, "Large mbuf pool could not be created\n"); return TEST_FAILED; } + /* Create mempool with smaller buffers for SGL testing */ + ts_params->small_mbuf_pool = rte_pktmbuf_pool_create("small_mbuf_pool", + NUM_LARGE_MBUFS * MAX_SEGS, + CACHE_SIZE, 0, + SMALL_SEG_SIZE + RTE_PKTMBUF_HEADROOM, + rte_socket_id()); + if (ts_params->small_mbuf_pool == NULL) { + RTE_LOG(ERR, USER1, "Small mbuf pool could not be created\n"); + goto exit; + } + ts_params->op_pool = rte_comp_op_pool_create("op_pool", NUM_OPS, - 0, 0, rte_socket_id()); + 0, sizeof(struct priv_op_data), + rte_socket_id()); if (ts_params->op_pool == NULL) { RTE_LOG(ERR, USER1, "Operation pool could not be created\n"); goto exit; } + ts_params->def_comp_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (ts_params->def_comp_xform == NULL) { + RTE_LOG(ERR, USER1, + "Default compress xform could not be created\n"); + goto exit; + } + ts_params->def_decomp_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + if (ts_params->def_decomp_xform == NULL) { + RTE_LOG(ERR, USER1, + "Default decompress xform could not be created\n"); + goto exit; + } + /* Initializes default values for compress/decompress xforms */ - ts_params->def_comp_xform.type = RTE_COMP_COMPRESS; - ts_params->def_comp_xform.compress.algo = RTE_COMP_ALGO_DEFLATE, - ts_params->def_comp_xform.compress.deflate.huffman = + ts_params->def_comp_xform->type = RTE_COMP_COMPRESS; + ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE, + ts_params->def_comp_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DEFAULT; - ts_params->def_comp_xform.compress.level = RTE_COMP_LEVEL_PMD_DEFAULT; - ts_params->def_comp_xform.compress.chksum = RTE_COMP_CHECKSUM_NONE; - ts_params->def_comp_xform.compress.window_size = DEFAULT_WINDOW_SIZE; + ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_PMD_DEFAULT; + ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE; + ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE; - ts_params->def_decomp_xform.type = RTE_COMP_DECOMPRESS; - ts_params->def_decomp_xform.decompress.algo = RTE_COMP_ALGO_DEFLATE, - ts_params->def_decomp_xform.decompress.chksum = RTE_COMP_CHECKSUM_NONE; - ts_params->def_decomp_xform.decompress.window_size = DEFAULT_WINDOW_SIZE; + ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS; + ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE, + ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE; + ts_params->def_decomp_xform->decompress.window_size = DEFAULT_WINDOW_SIZE; return TEST_SUCCESS; @@ -163,6 +205,51 @@ generic_ut_teardown(void) RTE_LOG(ERR, USER1, "Device could not be closed\n"); } +static int +test_compressdev_invalid_configuration(void) +{ + struct rte_compressdev_config invalid_config; + struct rte_compressdev_config valid_config = { + .socket_id = rte_socket_id(), + .nb_queue_pairs = 1, + .max_nb_priv_xforms = NUM_MAX_XFORMS, + .max_nb_streams = 0 + }; + struct rte_compressdev_info dev_info; + + /* Invalid configuration with 0 queue pairs */ + memcpy(&invalid_config, &valid_config, + sizeof(struct rte_compressdev_config)); + invalid_config.nb_queue_pairs = 0; + + TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), + "Device configuration was successful " + "with no queue pairs (invalid)\n"); + + /* + * Invalid configuration with too many queue pairs + * (if there is an actual maximum number of queue pairs) + */ + rte_compressdev_info_get(0, &dev_info); + if (dev_info.max_nb_queue_pairs != 0) { + memcpy(&invalid_config, &valid_config, + sizeof(struct rte_compressdev_config)); + invalid_config.nb_queue_pairs = dev_info.max_nb_queue_pairs + 1; + + TEST_ASSERT_FAIL(rte_compressdev_configure(0, &invalid_config), + "Device configuration was successful " + "with too many queue pairs (invalid)\n"); + } + + /* Invalid queue pair setup, with no number of queue pairs set */ + TEST_ASSERT_FAIL(rte_compressdev_queue_pair_setup(0, 0, + NUM_MAX_INFLIGHT_OPS, rte_socket_id()), + "Queue pair setup was successful " + "with no queue pairs set (invalid)\n"); + + return TEST_SUCCESS; +} + static int compare_buffers(const char *buffer1, uint32_t buffer1_len, const char *buffer2, uint32_t buffer2_len) @@ -211,7 +298,9 @@ compress_zlib(struct rte_comp_op *op, z_stream stream; int zlib_flush; int strategy, window_bits, comp_level; - int ret = -1; + int ret = TEST_FAILED; + uint8_t *single_src_buf = NULL; + uint8_t *single_dst_buf = NULL; /* initialize zlib stream */ stream.zalloc = Z_NULL; @@ -243,11 +332,39 @@ compress_zlib(struct rte_comp_op *op, } /* Assuming stateless operation */ - stream.avail_in = op->src.length; - stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); - stream.avail_out = op->m_dst->data_len; - stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); + /* SGL */ + if (op->m_src->nb_segs > 1) { + single_src_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_src), 0); + if (single_src_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + single_dst_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_dst), 0); + if (single_dst_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + if (rte_pktmbuf_read(op->m_src, 0, + rte_pktmbuf_pkt_len(op->m_src), + single_src_buf) == NULL) { + RTE_LOG(ERR, USER1, + "Buffer could not be read entirely\n"); + goto exit; + } + + stream.avail_in = op->src.length; + stream.next_in = single_src_buf; + stream.avail_out = rte_pktmbuf_pkt_len(op->m_dst); + stream.next_out = single_dst_buf; + } else { + stream.avail_in = op->src.length; + stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); + stream.avail_out = op->m_dst->data_len; + stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); + } /* Stateless operation, all buffer will be compressed in one go */ zlib_flush = map_zlib_flush_flag(op->flush_flag); ret = deflate(&stream, zlib_flush); @@ -260,8 +377,30 @@ compress_zlib(struct rte_comp_op *op, if (ret != Z_STREAM_END) goto exit; - op->consumed = op->src.length - stream.avail_in; - op->produced = op->m_dst->data_len - stream.avail_out; + /* Copy data to destination SGL */ + if (op->m_src->nb_segs > 1) { + uint32_t remaining_data = stream.total_out; + uint8_t *src_data = single_dst_buf; + struct rte_mbuf *dst_buf = op->m_dst; + + while (remaining_data > 0) { + uint8_t *dst_data = rte_pktmbuf_mtod(dst_buf, + uint8_t *); + /* Last segment */ + if (remaining_data < dst_buf->data_len) { + memcpy(dst_data, src_data, remaining_data); + remaining_data = 0; + } else { + memcpy(dst_data, src_data, dst_buf->data_len); + remaining_data -= dst_buf->data_len; + src_data += dst_buf->data_len; + dst_buf = dst_buf->next; + } + } + } + + op->consumed = stream.total_in; + op->produced = stream.total_out; op->status = RTE_COMP_OP_STATUS_SUCCESS; deflateReset(&stream); @@ -269,6 +408,8 @@ compress_zlib(struct rte_comp_op *op, ret = 0; exit: deflateEnd(&stream); + rte_free(single_src_buf); + rte_free(single_dst_buf); return ret; } @@ -281,6 +422,8 @@ decompress_zlib(struct rte_comp_op *op, int window_bits; int zlib_flush; int ret = TEST_FAILED; + uint8_t *single_src_buf = NULL; + uint8_t *single_dst_buf = NULL; /* initialize zlib stream */ stream.zalloc = Z_NULL; @@ -301,10 +444,39 @@ decompress_zlib(struct rte_comp_op *op, } /* Assuming stateless operation */ - stream.avail_in = op->src.length; - stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); - stream.avail_out = op->m_dst->data_len; - stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); + /* SGL */ + if (op->m_src->nb_segs > 1) { + single_src_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_src), 0); + if (single_src_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + single_dst_buf = rte_malloc(NULL, + rte_pktmbuf_pkt_len(op->m_dst), 0); + if (single_dst_buf == NULL) { + RTE_LOG(ERR, USER1, "Buffer could not be allocated\n"); + goto exit; + } + if (rte_pktmbuf_read(op->m_src, 0, + rte_pktmbuf_pkt_len(op->m_src), + single_src_buf) == NULL) { + RTE_LOG(ERR, USER1, + "Buffer could not be read entirely\n"); + goto exit; + } + + stream.avail_in = op->src.length; + stream.next_in = single_src_buf; + stream.avail_out = rte_pktmbuf_pkt_len(op->m_dst); + stream.next_out = single_dst_buf; + + } else { + stream.avail_in = op->src.length; + stream.next_in = rte_pktmbuf_mtod(op->m_src, uint8_t *); + stream.avail_out = op->m_dst->data_len; + stream.next_out = rte_pktmbuf_mtod(op->m_dst, uint8_t *); + } /* Stateless operation, all buffer will be compressed in one go */ zlib_flush = map_zlib_flush_flag(op->flush_flag); @@ -318,8 +490,29 @@ decompress_zlib(struct rte_comp_op *op, if (ret != Z_STREAM_END) goto exit; - op->consumed = op->src.length - stream.avail_in; - op->produced = op->m_dst->data_len - stream.avail_out; + if (op->m_src->nb_segs > 1) { + uint32_t remaining_data = stream.total_out; + uint8_t *src_data = single_dst_buf; + struct rte_mbuf *dst_buf = op->m_dst; + + while (remaining_data > 0) { + uint8_t *dst_data = rte_pktmbuf_mtod(dst_buf, + uint8_t *); + /* Last segment */ + if (remaining_data < dst_buf->data_len) { + memcpy(dst_data, src_data, remaining_data); + remaining_data = 0; + } else { + memcpy(dst_data, src_data, dst_buf->data_len); + remaining_data -= dst_buf->data_len; + src_data += dst_buf->data_len; + dst_buf = dst_buf->next; + } + } + } + + op->consumed = stream.total_in; + op->produced = stream.total_out; op->status = RTE_COMP_OP_STATUS_SUCCESS; inflateReset(&stream); @@ -331,107 +524,297 @@ exit: return ret; } +static int +prepare_sgl_bufs(const char *test_buf, struct rte_mbuf *head_buf, + uint32_t total_data_size, + struct rte_mempool *small_mbuf_pool, + struct rte_mempool *large_mbuf_pool, + uint8_t limit_segs_in_sgl) +{ + uint32_t remaining_data = total_data_size; + uint16_t num_remaining_segs = DIV_CEIL(remaining_data, SMALL_SEG_SIZE); + struct rte_mempool *pool; + struct rte_mbuf *next_seg; + uint32_t data_size; + char *buf_ptr; + const char *data_ptr = test_buf; + uint16_t i; + int ret; + + if (limit_segs_in_sgl != 0 && num_remaining_segs > limit_segs_in_sgl) + num_remaining_segs = limit_segs_in_sgl - 1; + + /* + * Allocate data in the first segment (header) and + * copy data if test buffer is provided + */ + if (remaining_data < SMALL_SEG_SIZE) + data_size = remaining_data; + else + data_size = SMALL_SEG_SIZE; + buf_ptr = rte_pktmbuf_append(head_buf, data_size); + if (buf_ptr == NULL) { + RTE_LOG(ERR, USER1, + "Not enough space in the 1st buffer\n"); + return -1; + } + + if (data_ptr != NULL) { + /* Copy characters without NULL terminator */ + strncpy(buf_ptr, data_ptr, data_size); + data_ptr += data_size; + } + remaining_data -= data_size; + num_remaining_segs--; + + /* + * Allocate the rest of the segments, + * copy the rest of the data and chain the segments. + */ + for (i = 0; i < num_remaining_segs; i++) { + + if (i == (num_remaining_segs - 1)) { + /* last segment */ + if (remaining_data > SMALL_SEG_SIZE) + pool = large_mbuf_pool; + else + pool = small_mbuf_pool; + data_size = remaining_data; + } else { + data_size = SMALL_SEG_SIZE; + pool = small_mbuf_pool; + } + + next_seg = rte_pktmbuf_alloc(pool); + if (next_seg == NULL) { + RTE_LOG(ERR, USER1, + "New segment could not be allocated " + "from the mempool\n"); + return -1; + } + buf_ptr = rte_pktmbuf_append(next_seg, data_size); + if (buf_ptr == NULL) { + RTE_LOG(ERR, USER1, + "Not enough space in the buffer\n"); + rte_pktmbuf_free(next_seg); + return -1; + } + if (data_ptr != NULL) { + /* Copy characters without NULL terminator */ + strncpy(buf_ptr, data_ptr, data_size); + data_ptr += data_size; + } + remaining_data -= data_size; + + ret = rte_pktmbuf_chain(head_buf, next_seg); + if (ret != 0) { + rte_pktmbuf_free(next_seg); + RTE_LOG(ERR, USER1, + "Segment could not chained\n"); + return -1; + } + } + + return 0; +} + /* * Compresses and decompresses buffer with compressdev API and Zlib API */ static int -test_deflate_comp_decomp(const char *test_buffer, - struct rte_comp_xform *compress_xform, - struct rte_comp_xform *decompress_xform, +test_deflate_comp_decomp(const char * const test_bufs[], + unsigned int num_bufs, + uint16_t buf_idx[], + struct rte_comp_xform *compress_xforms[], + struct rte_comp_xform *decompress_xforms[], + unsigned int num_xforms, enum rte_comp_op_type state, + unsigned int sgl, enum zlib_direction zlib_dir) { struct comp_testsuite_params *ts_params = &testsuite_params; int ret_status = -1; int ret; - struct rte_mbuf *comp_buf = NULL; - struct rte_mbuf *uncomp_buf = NULL; - struct rte_comp_op *op = NULL; - struct rte_comp_op *op_processed = NULL; - void *priv_xform = NULL; - uint16_t num_deqd; + struct rte_mbuf *uncomp_bufs[num_bufs]; + struct rte_mbuf *comp_bufs[num_bufs]; + struct rte_comp_op *ops[num_bufs]; + struct rte_comp_op *ops_processed[num_bufs]; + void *priv_xforms[num_bufs]; + uint16_t num_enqd, num_deqd, num_total_deqd; + uint16_t num_priv_xforms = 0; unsigned int deqd_retries = 0; - char *data_ptr; + struct priv_op_data *priv_data; + char *buf_ptr; + unsigned int i; + struct rte_mempool *buf_pool; + uint32_t data_size; + const struct rte_compressdev_capabilities *capa = + rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + char *contig_buf = NULL; + + /* Initialize all arrays to NULL */ + memset(uncomp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); + memset(comp_bufs, 0, sizeof(struct rte_mbuf *) * num_bufs); + memset(ops, 0, sizeof(struct rte_comp_op *) * num_bufs); + memset(ops_processed, 0, sizeof(struct rte_comp_op *) * num_bufs); + memset(priv_xforms, 0, sizeof(void *) * num_bufs); + + if (sgl) + buf_pool = ts_params->small_mbuf_pool; + else + buf_pool = ts_params->large_mbuf_pool; - /* Prepare the source mbuf with the data */ - uncomp_buf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - if (uncomp_buf == NULL) { + /* Prepare the source mbufs with the data */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, + uncomp_bufs, num_bufs); + if (ret < 0) { RTE_LOG(ERR, USER1, - "Source mbuf could not be allocated " + "Source mbufs could not be allocated " "from the mempool\n"); goto exit; } - data_ptr = rte_pktmbuf_append(uncomp_buf, strlen(test_buffer) + 1); - snprintf(data_ptr, strlen(test_buffer) + 1, "%s", test_buffer); + if (sgl) { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) + 1; + if (prepare_sgl_bufs(test_bufs[i], uncomp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + } else { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) + 1; + buf_ptr = rte_pktmbuf_append(uncomp_bufs[i], data_size); + snprintf(buf_ptr, data_size, "%s", test_bufs[i]); + } + } - /* Prepare the destination mbuf */ - comp_buf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - if (comp_buf == NULL) { + /* Prepare the destination mbufs */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, comp_bufs, num_bufs); + if (ret < 0) { RTE_LOG(ERR, USER1, - "Destination mbuf could not be allocated " + "Destination mbufs could not be allocated " "from the mempool\n"); goto exit; } - rte_pktmbuf_append(comp_buf, - strlen(test_buffer) * COMPRESS_BUF_SIZE_RATIO); + if (sgl) { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) * + COMPRESS_BUF_SIZE_RATIO; + if (prepare_sgl_bufs(NULL, comp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + + } else { + for (i = 0; i < num_bufs; i++) { + data_size = strlen(test_bufs[i]) * + COMPRESS_BUF_SIZE_RATIO; + rte_pktmbuf_append(comp_bufs[i], data_size); + } + } /* Build the compression operations */ - op = rte_comp_op_alloc(ts_params->op_pool); - if (op == NULL) { + ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); + if (ret < 0) { RTE_LOG(ERR, USER1, - "Compress operation could not be allocated " + "Compress operations could not be allocated " "from the mempool\n"); goto exit; } - op->m_src = uncomp_buf; - op->m_dst = comp_buf; - op->src.offset = 0; - op->src.length = rte_pktmbuf_pkt_len(uncomp_buf); - op->dst.offset = 0; - if (state == RTE_COMP_OP_STATELESS) { - op->flush_flag = RTE_COMP_FLUSH_FINAL; - } else { - RTE_LOG(ERR, USER1, - "Stateful operations are not supported " - "in these tests yet\n"); - goto exit; + for (i = 0; i < num_bufs; i++) { + ops[i]->m_src = uncomp_bufs[i]; + ops[i]->m_dst = comp_bufs[i]; + ops[i]->src.offset = 0; + ops[i]->src.length = rte_pktmbuf_pkt_len(uncomp_bufs[i]); + ops[i]->dst.offset = 0; + if (state == RTE_COMP_OP_STATELESS) { + ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; + } else { + RTE_LOG(ERR, USER1, + "Stateful operations are not supported " + "in these tests yet\n"); + goto exit; + } + ops[i]->input_chksum = 0; + /* + * Store original operation index in private data, + * since ordering does not have to be maintained, + * when dequeueing from compressdev, so a comparison + * at the end of the test can be done. + */ + priv_data = (struct priv_op_data *) (ops[i] + 1); + priv_data->orig_idx = i; } - op->input_chksum = 0; /* Compress data (either with Zlib API or compressdev API */ if (zlib_dir == ZLIB_COMPRESS || zlib_dir == ZLIB_ALL) { - ret = compress_zlib(op, - (const struct rte_comp_xform *)&compress_xform, - DEFAULT_MEM_LEVEL); - if (ret < 0) - goto exit; - - op_processed = op; + for (i = 0; i < num_bufs; i++) { + const struct rte_comp_xform *compress_xform = + compress_xforms[i % num_xforms]; + ret = compress_zlib(ops[i], compress_xform, + DEFAULT_MEM_LEVEL); + if (ret < 0) + goto exit; + + ops_processed[i] = ops[i]; + } } else { - /* Create compress xform private data */ - ret = rte_compressdev_private_xform_create(0, - (const struct rte_comp_xform *)compress_xform, - &priv_xform); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Compression private xform " - "could not be created\n"); - goto exit; + /* Create compress private xform data */ + for (i = 0; i < num_xforms; i++) { + ret = rte_compressdev_private_xform_create(0, + (const struct rte_comp_xform *)compress_xforms[i], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Compression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; } - /* Attach xform private data to operation */ - op->private_xform = priv_xform; + if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { + /* Attach shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) + ops[i]->private_xform = priv_xforms[i % num_xforms]; + } else { + /* Create rest of the private xforms for the other ops */ + for (i = num_xforms; i < num_bufs; i++) { + ret = rte_compressdev_private_xform_create(0, + compress_xforms[i % num_xforms], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Compression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + /* Attach non shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) + ops[i]->private_xform = priv_xforms[i]; + } /* Enqueue and dequeue all operations */ - ret = rte_compressdev_enqueue_burst(0, 0, &op, 1); - if (ret == 0) { + num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); + if (num_enqd < num_bufs) { RTE_LOG(ERR, USER1, - "The operation could not be enqueued\n"); + "The operations could not be enqueued\n"); goto exit; } + + num_total_deqd = 0; do { /* * If retrying a dequeue call, wait for 10 ms to allow @@ -451,120 +834,201 @@ test_deflate_comp_decomp(const char *test_buffer, usleep(DEQUEUE_WAIT_TIME); } num_deqd = rte_compressdev_dequeue_burst(0, 0, - &op_processed, 1); - + &ops_processed[num_total_deqd], num_bufs); + num_total_deqd += num_deqd; deqd_retries++; - } while (num_deqd < 1); + } while (num_total_deqd < num_enqd); deqd_retries = 0; - /* Free compress private xform */ - rte_compressdev_private_xform_free(0, priv_xform); - priv_xform = NULL; + /* Free compress private xforms */ + for (i = 0; i < num_priv_xforms; i++) { + rte_compressdev_private_xform_free(0, priv_xforms[i]); + priv_xforms[i] = NULL; + } + num_priv_xforms = 0; } - enum rte_comp_huffman huffman_type = - compress_xform->compress.deflate.huffman; - RTE_LOG(DEBUG, USER1, "Buffer compressed from %u to %u bytes " - "(level = %u, huffman = %s)\n", - op_processed->consumed, op_processed->produced, - compress_xform->compress.level, + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % num_xforms; + const struct rte_comp_compress_xform *compress_xform = + &compress_xforms[xform_idx]->compress; + enum rte_comp_huffman huffman_type = + compress_xform->deflate.huffman; + RTE_LOG(DEBUG, USER1, "Buffer %u compressed from %u to %u bytes " + "(level = %d, huffman = %s)\n", + buf_idx[priv_data->orig_idx], + ops_processed[i]->consumed, ops_processed[i]->produced, + compress_xform->level, huffman_type_strings[huffman_type]); - RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f", - (float)op_processed->produced / - op_processed->consumed * 100); - op = NULL; + RTE_LOG(DEBUG, USER1, "Compression ratio = %.2f", + (float)ops_processed[i]->produced / + ops_processed[i]->consumed * 100); + ops[i] = NULL; + } /* - * Check operation status and free source mbuf (destination mbuf and + * Check operation status and free source mbufs (destination mbuf and * compress operation information is needed for the decompression stage) */ - if (op_processed->status != RTE_COMP_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "Some operations were not successful\n"); - goto exit; + for (i = 0; i < num_bufs; i++) { + if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "Some operations were not successful\n"); + goto exit; + } + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + rte_pktmbuf_free(uncomp_bufs[priv_data->orig_idx]); + uncomp_bufs[priv_data->orig_idx] = NULL; } - rte_pktmbuf_free(uncomp_buf); - uncomp_buf = NULL; - /* Allocate buffer for decompressed data */ - uncomp_buf = rte_pktmbuf_alloc(ts_params->mbuf_pool); - if (uncomp_buf == NULL) { + /* Allocate buffers for decompressed data */ + ret = rte_pktmbuf_alloc_bulk(buf_pool, uncomp_bufs, num_bufs); + if (ret < 0) { RTE_LOG(ERR, USER1, - "Destination mbuf could not be allocated " + "Destination mbufs could not be allocated " "from the mempool\n"); goto exit; } - rte_pktmbuf_append(uncomp_buf, strlen(test_buffer) + 1); + if (sgl) { + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *) + (ops_processed[i] + 1); + data_size = strlen(test_bufs[priv_data->orig_idx]) + 1; + if (prepare_sgl_bufs(NULL, uncomp_bufs[i], + data_size, + ts_params->small_mbuf_pool, + ts_params->large_mbuf_pool, + MAX_SEGS) < 0) + goto exit; + } + + } else { + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *) + (ops_processed[i] + 1); + data_size = strlen(test_bufs[priv_data->orig_idx]) + 1; + rte_pktmbuf_append(uncomp_bufs[i], data_size); + } + } /* Build the decompression operations */ - op = rte_comp_op_alloc(ts_params->op_pool); - if (op == NULL) { + ret = rte_comp_op_bulk_alloc(ts_params->op_pool, ops, num_bufs); + if (ret < 0) { RTE_LOG(ERR, USER1, - "Decompress operation could not be allocated " + "Decompress operations could not be allocated " "from the mempool\n"); goto exit; } - /* Source buffer is the compressed data from the previous operation */ - op->m_src = op_processed->m_dst; - op->m_dst = uncomp_buf; - op->src.offset = 0; - /* - * Set the length of the compressed data to the - * number of bytes that were produced in the previous stage - */ - op->src.length = op_processed->produced; - op->dst.offset = 0; - if (state == RTE_COMP_OP_STATELESS) { - op->flush_flag = RTE_COMP_FLUSH_FINAL; - } else { - RTE_LOG(ERR, USER1, - "Stateful operations are not supported " - "in these tests yet\n"); - goto exit; + /* Source buffer is the compressed data from the previous operations */ + for (i = 0; i < num_bufs; i++) { + ops[i]->m_src = ops_processed[i]->m_dst; + ops[i]->m_dst = uncomp_bufs[i]; + ops[i]->src.offset = 0; + /* + * Set the length of the compressed data to the + * number of bytes that were produced in the previous stage + */ + ops[i]->src.length = ops_processed[i]->produced; + ops[i]->dst.offset = 0; + if (state == RTE_COMP_OP_STATELESS) { + ops[i]->flush_flag = RTE_COMP_FLUSH_FINAL; + } else { + RTE_LOG(ERR, USER1, + "Stateful operations are not supported " + "in these tests yet\n"); + goto exit; + } + ops[i]->input_chksum = 0; + /* + * Copy private data from previous operations, + * to keep the pointer to the original buffer + */ + memcpy(ops[i] + 1, ops_processed[i] + 1, + sizeof(struct priv_op_data)); } - op->input_chksum = 0; /* - * Free the previous compress operation, + * Free the previous compress operations, * as it is not needed anymore */ - rte_comp_op_free(op_processed); - op_processed = NULL; + for (i = 0; i < num_bufs; i++) { + rte_comp_op_free(ops_processed[i]); + ops_processed[i] = NULL; + } /* Decompress data (either with Zlib API or compressdev API */ if (zlib_dir == ZLIB_DECOMPRESS || zlib_dir == ZLIB_ALL) { - ret = decompress_zlib(op, - (const struct rte_comp_xform *)&decompress_xform); - if (ret < 0) - goto exit; + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % num_xforms; + const struct rte_comp_xform *decompress_xform = + decompress_xforms[xform_idx]; - op_processed = op; + ret = decompress_zlib(ops[i], decompress_xform); + if (ret < 0) + goto exit; + + ops_processed[i] = ops[i]; + } } else { - num_deqd = 0; - /* Create decompress xform private data */ - ret = rte_compressdev_private_xform_create(0, - (const struct rte_comp_xform *)decompress_xform, - &priv_xform); - if (ret < 0) { - RTE_LOG(ERR, USER1, - "Decompression private xform " - "could not be created\n"); - goto exit; + /* Create decompress private xform data */ + for (i = 0; i < num_xforms; i++) { + ret = rte_compressdev_private_xform_create(0, + (const struct rte_comp_xform *)decompress_xforms[i], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Decompression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; } - /* Attach xform private data to operation */ - op->private_xform = priv_xform; + if (capa->comp_feature_flags & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) { + /* Attach shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx % + num_xforms; + ops[i]->private_xform = priv_xforms[xform_idx]; + } + } else { + /* Create rest of the private xforms for the other ops */ + for (i = num_xforms; i < num_bufs; i++) { + ret = rte_compressdev_private_xform_create(0, + decompress_xforms[i % num_xforms], + &priv_xforms[i]); + if (ret < 0) { + RTE_LOG(ERR, USER1, + "Decompression private xform " + "could not be created\n"); + goto exit; + } + num_priv_xforms++; + } + + /* Attach non shareable private xform data to ops */ + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops[i] + 1); + uint16_t xform_idx = priv_data->orig_idx; + ops[i]->private_xform = priv_xforms[xform_idx]; + } + } /* Enqueue and dequeue all operations */ - ret = rte_compressdev_enqueue_burst(0, 0, &op, 1); - if (ret == 0) { + num_enqd = rte_compressdev_enqueue_burst(0, 0, ops, num_bufs); + if (num_enqd < num_bufs) { RTE_LOG(ERR, USER1, - "The operation could not be enqueued\n"); + "The operations could not be enqueued\n"); goto exit; } + + num_total_deqd = 0; do { /* * If retrying a dequeue call, wait for 10 ms to allow @@ -584,47 +1048,78 @@ test_deflate_comp_decomp(const char *test_buffer, usleep(DEQUEUE_WAIT_TIME); } num_deqd = rte_compressdev_dequeue_burst(0, 0, - &op_processed, 1); - + &ops_processed[num_total_deqd], num_bufs); + num_total_deqd += num_deqd; deqd_retries++; - } while (num_deqd < 1); + } while (num_total_deqd < num_enqd); + + deqd_retries = 0; + } + + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + RTE_LOG(DEBUG, USER1, "Buffer %u decompressed from %u to %u bytes\n", + buf_idx[priv_data->orig_idx], + ops_processed[i]->consumed, ops_processed[i]->produced); + ops[i] = NULL; } - RTE_LOG(DEBUG, USER1, "Buffer decompressed from %u to %u bytes\n", - op_processed->consumed, op_processed->produced); - op = NULL; /* * Check operation status and free source mbuf (destination mbuf and * compress operation information is still needed) */ - if (op_processed->status != RTE_COMP_OP_STATUS_SUCCESS) { - RTE_LOG(ERR, USER1, - "Some operations were not successful\n"); - goto exit; + for (i = 0; i < num_bufs; i++) { + if (ops_processed[i]->status != RTE_COMP_OP_STATUS_SUCCESS) { + RTE_LOG(ERR, USER1, + "Some operations were not successful\n"); + goto exit; + } + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + rte_pktmbuf_free(comp_bufs[priv_data->orig_idx]); + comp_bufs[priv_data->orig_idx] = NULL; } - rte_pktmbuf_free(comp_buf); - comp_buf = NULL; /* * Compare the original stream with the decompressed stream * (in size and the data) */ - if (compare_buffers(test_buffer, strlen(test_buffer) + 1, - rte_pktmbuf_mtod(op_processed->m_dst, const char *), - op_processed->produced) < 0) - goto exit; + for (i = 0; i < num_bufs; i++) { + priv_data = (struct priv_op_data *)(ops_processed[i] + 1); + const char *buf1 = test_bufs[priv_data->orig_idx]; + const char *buf2; + contig_buf = rte_malloc(NULL, ops_processed[i]->produced, 0); + if (contig_buf == NULL) { + RTE_LOG(ERR, USER1, "Contiguous buffer could not " + "be allocated\n"); + goto exit; + } + + buf2 = rte_pktmbuf_read(ops_processed[i]->m_dst, 0, + ops_processed[i]->produced, contig_buf); + + if (compare_buffers(buf1, strlen(buf1) + 1, + buf2, ops_processed[i]->produced) < 0) + goto exit; + + rte_free(contig_buf); + contig_buf = NULL; + } ret_status = 0; exit: /* Free resources */ - rte_pktmbuf_free(uncomp_buf); - rte_pktmbuf_free(comp_buf); - rte_comp_op_free(op); - rte_comp_op_free(op_processed); - - if (priv_xform != NULL) - rte_compressdev_private_xform_free(0, priv_xform); + for (i = 0; i < num_bufs; i++) { + rte_pktmbuf_free(uncomp_bufs[i]); + rte_pktmbuf_free(comp_bufs[i]); + rte_comp_op_free(ops[i]); + rte_comp_op_free(ops_processed[i]); + } + for (i = 0; i < num_priv_xforms; i++) { + if (priv_xforms[i] != NULL) + rte_compressdev_private_xform_free(0, priv_xforms[i]); + } + rte_free(contig_buf); return ret_status; } @@ -635,33 +1130,64 @@ test_compressdev_deflate_stateless_fixed(void) struct comp_testsuite_params *ts_params = &testsuite_params; const char *test_buffer; uint16_t i; - struct rte_comp_xform compress_xform; + int ret; + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_FIXED) == 0) + return -ENOTSUP; + + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); - memcpy(&compress_xform, &ts_params->def_comp_xform, + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, sizeof(struct rte_comp_xform)); - compress_xform.compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED; + compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_FIXED; for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { test_buffer = compress_test_bufs[i]; /* Compress with compressdev, decompress with Zlib */ - if (test_deflate_comp_decomp(test_buffer, + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, &compress_xform, &ts_params->def_decomp_xform, + 1, RTE_COMP_OP_STATELESS, - ZLIB_DECOMPRESS) < 0) - return TEST_FAILED; + 0, + ZLIB_DECOMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } /* Compress with Zlib, decompress with compressdev */ - if (test_deflate_comp_decomp(test_buffer, + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, &compress_xform, &ts_params->def_decomp_xform, + 1, RTE_COMP_OP_STATELESS, - ZLIB_COMPRESS) < 0) - return TEST_FAILED; + 0, + ZLIB_COMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } } - return TEST_SUCCESS; + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; } static int @@ -670,28 +1196,257 @@ test_compressdev_deflate_stateless_dynamic(void) struct comp_testsuite_params *ts_params = &testsuite_params; const char *test_buffer; uint16_t i; - struct rte_comp_xform compress_xform; + int ret; + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_HUFFMAN_DYNAMIC) == 0) + return -ENOTSUP; - memcpy(&compress_xform, &ts_params->def_comp_xform, + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, sizeof(struct rte_comp_xform)); - compress_xform.compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC; + compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC; for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { test_buffer = compress_test_bufs[i]; /* Compress with compressdev, decompress with Zlib */ - if (test_deflate_comp_decomp(test_buffer, + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, &compress_xform, &ts_params->def_decomp_xform, + 1, RTE_COMP_OP_STATELESS, + 0, + ZLIB_DECOMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } + + /* Compress with Zlib, decompress with compressdev */ + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, + &compress_xform, + &ts_params->def_decomp_xform, + 1, + RTE_COMP_OP_STATELESS, + 0, + ZLIB_COMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + +static int +test_compressdev_deflate_stateless_multi_op(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t num_bufs = RTE_DIM(compress_test_bufs); + uint16_t buf_idx[num_bufs]; + uint16_t i; + + for (i = 0; i < num_bufs; i++) + buf_idx[i] = i; + + /* Compress with compressdev, decompress with Zlib */ + if (test_deflate_comp_decomp(compress_test_bufs, num_bufs, + buf_idx, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1, + RTE_COMP_OP_STATELESS, + 0, + ZLIB_DECOMPRESS) < 0) + return TEST_FAILED; + + /* Compress with Zlib, decompress with compressdev */ + if (test_deflate_comp_decomp(compress_test_bufs, num_bufs, + buf_idx, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1, + RTE_COMP_OP_STATELESS, + 0, + ZLIB_COMPRESS) < 0) + return TEST_FAILED; + + return TEST_SUCCESS; +} + +static int +test_compressdev_deflate_stateless_multi_level(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + const char *test_buffer; + unsigned int level; + uint16_t i; + int ret; + struct rte_comp_xform *compress_xform = + rte_malloc(NULL, sizeof(struct rte_comp_xform), 0); + + if (compress_xform == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xform, ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + test_buffer = compress_test_bufs[i]; + for (level = RTE_COMP_LEVEL_MIN; level <= RTE_COMP_LEVEL_MAX; + level++) { + compress_xform->compress.level = level; + /* Compress with compressdev, decompress with Zlib */ + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, + &compress_xform, + &ts_params->def_decomp_xform, + 1, + RTE_COMP_OP_STATELESS, + 0, + ZLIB_DECOMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } + } + } + + ret = TEST_SUCCESS; + +exit: + rte_free(compress_xform); + return ret; +} + +#define NUM_XFORMS 3 +static int +test_compressdev_deflate_stateless_multi_xform(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t num_bufs = NUM_XFORMS; + struct rte_comp_xform *compress_xforms[NUM_XFORMS] = {NULL}; + struct rte_comp_xform *decompress_xforms[NUM_XFORMS] = {NULL}; + const char *test_buffers[NUM_XFORMS]; + uint16_t i; + unsigned int level = RTE_COMP_LEVEL_MIN; + uint16_t buf_idx[num_bufs]; + + int ret; + + /* Create multiple xforms with various levels */ + for (i = 0; i < NUM_XFORMS; i++) { + compress_xforms[i] = rte_malloc(NULL, + sizeof(struct rte_comp_xform), 0); + if (compress_xforms[i] == NULL) { + RTE_LOG(ERR, USER1, + "Compress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(compress_xforms[i], ts_params->def_comp_xform, + sizeof(struct rte_comp_xform)); + compress_xforms[i]->compress.level = level; + level++; + + decompress_xforms[i] = rte_malloc(NULL, + sizeof(struct rte_comp_xform), 0); + if (decompress_xforms[i] == NULL) { + RTE_LOG(ERR, USER1, + "Decompress xform could not be created\n"); + ret = TEST_FAILED; + goto exit; + } + + memcpy(decompress_xforms[i], ts_params->def_decomp_xform, + sizeof(struct rte_comp_xform)); + } + + for (i = 0; i < NUM_XFORMS; i++) { + buf_idx[i] = 0; + /* Use the same buffer in all sessions */ + test_buffers[i] = compress_test_bufs[0]; + } + /* Compress with compressdev, decompress with Zlib */ + if (test_deflate_comp_decomp(test_buffers, num_bufs, + buf_idx, + compress_xforms, + decompress_xforms, + NUM_XFORMS, + RTE_COMP_OP_STATELESS, + 0, + ZLIB_DECOMPRESS) < 0) { + ret = TEST_FAILED; + goto exit; + } + + ret = TEST_SUCCESS; +exit: + for (i = 0; i < NUM_XFORMS; i++) { + rte_free(compress_xforms[i]); + rte_free(decompress_xforms[i]); + } + + return ret; +} + +static int +test_compressdev_deflate_stateless_sgl(void) +{ + struct comp_testsuite_params *ts_params = &testsuite_params; + uint16_t i; + const char *test_buffer; + const struct rte_compressdev_capabilities *capab; + + capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities"); + + if ((capab->comp_feature_flags & RTE_COMP_FF_OOP_SGL_IN_SGL_OUT) == 0) + return -ENOTSUP; + + for (i = 0; i < RTE_DIM(compress_test_bufs); i++) { + test_buffer = compress_test_bufs[i]; + /* Compress with compressdev, decompress with Zlib */ + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, + &ts_params->def_comp_xform, + &ts_params->def_decomp_xform, + 1, + RTE_COMP_OP_STATELESS, + 1, ZLIB_DECOMPRESS) < 0) return TEST_FAILED; /* Compress with Zlib, decompress with compressdev */ - if (test_deflate_comp_decomp(test_buffer, - &compress_xform, + if (test_deflate_comp_decomp(&test_buffer, 1, + &i, + &ts_params->def_comp_xform, &ts_params->def_decomp_xform, + 1, RTE_COMP_OP_STATELESS, + 1, ZLIB_COMPRESS) < 0) return TEST_FAILED; } @@ -704,10 +1459,20 @@ static struct unit_test_suite compressdev_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { + TEST_CASE_ST(NULL, NULL, + test_compressdev_invalid_configuration), TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, test_compressdev_deflate_stateless_fixed), TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, test_compressdev_deflate_stateless_dynamic), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_op), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_level), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_multi_xform), + TEST_CASE_ST(generic_ut_setup, generic_ut_teardown, + test_compressdev_deflate_stateless_sgl), TEST_CASES_END() /**< NULL terminate unit test array */ } };