1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
5 #include <rte_malloc.h>
8 #include <rte_compressdev.h>
10 #include "comp_perf_test_verify.h"
11 #include "comp_perf_test_common.h"
14 cperf_verify_test_destructor(void *arg)
17 comp_perf_free_memory(
18 ((struct cperf_verify_ctx *)arg)->options,
19 &((struct cperf_verify_ctx *)arg)->mem);
25 cperf_verify_test_constructor(uint8_t dev_id, uint16_t qp_id,
26 struct comp_test_data *options)
28 struct cperf_verify_ctx *ctx = NULL;
30 ctx = rte_malloc(NULL, sizeof(struct cperf_verify_ctx), 0);
35 ctx->mem.dev_id = dev_id;
36 ctx->mem.qp_id = qp_id;
37 ctx->options = options;
39 if (!comp_perf_allocate_memory(ctx->options, &ctx->mem) &&
40 !prepare_bufs(ctx->options, &ctx->mem))
43 cperf_verify_test_destructor(ctx);
48 main_loop(struct cperf_verify_ctx *ctx, enum rte_comp_xform_type type)
50 struct comp_test_data *test_data = ctx->options;
51 uint8_t *output_data_ptr = NULL;
52 size_t *output_data_sz = NULL;
53 struct cperf_mem_resources *mem = &ctx->mem;
55 uint8_t dev_id = mem->dev_id;
56 uint32_t i, iter, num_iter;
57 struct rte_comp_op **ops, **deq_ops;
58 void *priv_xform = NULL;
59 struct rte_comp_xform xform;
60 size_t output_size = 0;
61 struct rte_mbuf **input_bufs, **output_bufs;
66 if (test_data == NULL || !test_data->burst_sz) {
68 "Unknown burst size\n");
72 ops = rte_zmalloc_socket(NULL,
73 2 * mem->total_bufs * sizeof(struct rte_comp_op *),
78 "Can't allocate memory for ops strucures\n");
82 deq_ops = &ops[mem->total_bufs];
84 if (type == RTE_COMP_COMPRESS) {
85 xform = (struct rte_comp_xform) {
86 .type = RTE_COMP_COMPRESS,
88 .algo = RTE_COMP_ALGO_DEFLATE,
89 .deflate.huffman = test_data->huffman_enc,
90 .level = test_data->level,
91 .window_size = test_data->window_sz,
92 .chksum = RTE_COMP_CHECKSUM_NONE,
93 .hash_algo = RTE_COMP_HASH_ALGO_NONE
96 output_data_ptr = ctx->mem.compressed_data;
97 output_data_sz = &ctx->comp_data_sz;
98 input_bufs = mem->decomp_bufs;
99 output_bufs = mem->comp_bufs;
100 out_seg_sz = test_data->out_seg_sz;
102 xform = (struct rte_comp_xform) {
103 .type = RTE_COMP_DECOMPRESS,
105 .algo = RTE_COMP_ALGO_DEFLATE,
106 .chksum = RTE_COMP_CHECKSUM_NONE,
107 .window_size = test_data->window_sz,
108 .hash_algo = RTE_COMP_HASH_ALGO_NONE
111 output_data_ptr = ctx->mem.decompressed_data;
112 output_data_sz = &ctx->decomp_data_sz;
113 input_bufs = mem->comp_bufs;
114 output_bufs = mem->decomp_bufs;
115 out_seg_sz = test_data->seg_sz;
118 /* Create private xform */
119 if (rte_compressdev_private_xform_create(dev_id, &xform,
121 RTE_LOG(ERR, USER1, "Private xform could not be created\n");
128 for (iter = 0; iter < num_iter; iter++) {
129 uint32_t total_ops = mem->total_bufs;
130 uint32_t remaining_ops = mem->total_bufs;
131 uint32_t total_deq_ops = 0;
132 uint32_t total_enq_ops = 0;
133 uint16_t ops_unused = 0;
134 uint16_t num_enq = 0;
135 uint16_t num_deq = 0;
139 while (remaining_ops > 0) {
140 uint16_t num_ops = RTE_MIN(remaining_ops,
141 test_data->burst_sz);
142 uint16_t ops_needed = num_ops - ops_unused;
145 * Move the unused operations from the previous
146 * enqueue_burst call to the front, to maintain order
148 if ((ops_unused > 0) && (num_enq > 0)) {
150 ops_unused * sizeof(struct rte_comp_op *);
152 memmove(ops, &ops[num_enq], nb_b_to_mov);
155 /* Allocate compression operations */
156 if (ops_needed && !rte_comp_op_bulk_alloc(
161 "Could not allocate enough operations\n");
165 allocated += ops_needed;
167 for (i = 0; i < ops_needed; i++) {
169 * Calculate next buffer to attach to operation
171 uint32_t buf_id = total_enq_ops + i +
173 uint16_t op_id = ops_unused + i;
174 /* Reset all data in output buffers */
175 struct rte_mbuf *m = output_bufs[buf_id];
177 m->pkt_len = out_seg_sz * m->nb_segs;
179 m->data_len = m->buf_len - m->data_off;
182 ops[op_id]->m_src = input_bufs[buf_id];
183 ops[op_id]->m_dst = output_bufs[buf_id];
184 ops[op_id]->src.offset = 0;
185 ops[op_id]->src.length =
186 rte_pktmbuf_pkt_len(input_bufs[buf_id]);
187 ops[op_id]->dst.offset = 0;
188 ops[op_id]->flush_flag = RTE_COMP_FLUSH_FINAL;
189 ops[op_id]->input_chksum = buf_id;
190 ops[op_id]->private_xform = priv_xform;
193 if (unlikely(test_data->perf_comp_force_stop))
196 num_enq = rte_compressdev_enqueue_burst(dev_id,
200 struct rte_compressdev_stats stats;
202 rte_compressdev_stats_get(dev_id, &stats);
203 if (stats.enqueue_err_count) {
209 ops_unused = num_ops - num_enq;
210 remaining_ops -= num_enq;
211 total_enq_ops += num_enq;
213 num_deq = rte_compressdev_dequeue_burst(dev_id,
216 test_data->burst_sz);
217 total_deq_ops += num_deq;
219 for (i = 0; i < num_deq; i++) {
220 struct rte_comp_op *op = deq_ops[i];
223 RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED ||
225 RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE) {
227 "Out of space error occurred due to uncompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n");
230 } else if (op->status !=
231 RTE_COMP_OP_STATUS_SUCCESS) {
233 "Some operations were not successful\n");
237 const void *read_data_addr =
238 rte_pktmbuf_read(op->m_dst, 0,
239 op->produced, output_data_ptr);
240 if (read_data_addr == NULL) {
242 "Could not copy buffer in destination\n");
247 if (read_data_addr != output_data_ptr)
248 rte_memcpy(output_data_ptr,
249 rte_pktmbuf_mtod(op->m_dst,
252 output_data_ptr += op->produced;
253 output_size += op->produced;
258 if (iter == num_iter - 1) {
259 for (i = 0; i < num_deq; i++) {
260 struct rte_comp_op *op = deq_ops[i];
261 struct rte_mbuf *m = op->m_dst;
263 m->pkt_len = op->produced;
264 uint32_t remaining_data = op->produced;
265 uint16_t data_to_append;
267 while (remaining_data > 0) {
269 RTE_MIN(remaining_data,
271 m->data_len = data_to_append;
278 rte_mempool_put_bulk(mem->op_pool,
279 (void **)deq_ops, num_deq);
280 allocated -= num_deq;
283 /* Dequeue the last operations */
284 while (total_deq_ops < total_ops) {
285 if (unlikely(test_data->perf_comp_force_stop))
288 num_deq = rte_compressdev_dequeue_burst(dev_id,
291 test_data->burst_sz);
293 struct rte_compressdev_stats stats;
295 rte_compressdev_stats_get(dev_id, &stats);
296 if (stats.dequeue_err_count) {
302 total_deq_ops += num_deq;
304 for (i = 0; i < num_deq; i++) {
305 struct rte_comp_op *op = deq_ops[i];
308 RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED ||
310 RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE) {
312 "Out of space error occurred due to uncompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n");
315 } else if (op->status !=
316 RTE_COMP_OP_STATUS_SUCCESS) {
318 "Some operations were not successful\n");
321 const void *read_data_addr =
322 rte_pktmbuf_read(op->m_dst,
324 op->produced, output_data_ptr);
325 if (read_data_addr == NULL) {
327 "Could not copy buffer in destination\n");
332 if (read_data_addr != output_data_ptr)
333 rte_memcpy(output_data_ptr,
335 op->m_dst, uint8_t *),
337 output_data_ptr += op->produced;
338 output_size += op->produced;
342 if (iter == num_iter - 1) {
343 for (i = 0; i < num_deq; i++) {
344 struct rte_comp_op *op = deq_ops[i];
345 struct rte_mbuf *m = op->m_dst;
347 m->pkt_len = op->produced;
348 uint32_t remaining_data = op->produced;
349 uint16_t data_to_append;
351 while (remaining_data > 0) {
353 RTE_MIN(remaining_data,
355 m->data_len = data_to_append;
362 rte_mempool_put_bulk(mem->op_pool,
363 (void **)deq_ops, num_deq);
364 allocated -= num_deq;
369 *output_data_sz = output_size;
371 rte_mempool_put_bulk(mem->op_pool, (void **)ops, allocated);
372 rte_compressdev_private_xform_free(dev_id, priv_xform);
375 if (test_data->perf_comp_force_stop) {
377 "lcore: %d Perf. test has been aborted by user\n",
386 cperf_verify_test_runner(void *test_ctx)
388 struct cperf_verify_ctx *ctx = test_ctx;
389 struct comp_test_data *test_data = ctx->options;
390 int ret = EXIT_SUCCESS;
391 static rte_atomic16_t display_once = RTE_ATOMIC16_INIT(0);
392 uint32_t lcore = rte_lcore_id();
394 ctx->mem.lcore_id = lcore;
396 test_data->ratio = 0;
398 if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) {
403 if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) {
408 if (ctx->decomp_data_sz != test_data->input_data_sz) {
410 "Decompressed data length not equal to input data length\n");
412 "Decompressed size = %zu, expected = %zu\n",
413 ctx->decomp_data_sz, test_data->input_data_sz);
417 if (memcmp(ctx->mem.decompressed_data,
418 test_data->input_data,
419 test_data->input_data_sz) != 0) {
421 "Decompressed data is not the same as file data\n");
427 ctx->ratio = (double) ctx->comp_data_sz /
428 test_data->input_data_sz * 100;
431 if (rte_atomic16_test_and_set(&display_once)) {
432 printf("%12s%6s%12s%17s\n",
433 "lcore id", "Level", "Comp size", "Comp ratio [%]");
435 printf("%12u%6u%12zu%17.2f\n",
437 test_data->level, ctx->comp_data_sz, ctx->ratio);