app/compress-perf: call generic strlcpy
[dpdk.git] / app / test-compress-perf / comp_perf_test_verify.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_eal.h>
7 #include <rte_log.h>
8 #include <rte_compressdev.h>
9
10 #include "comp_perf_test_verify.h"
11
12 static int
13 main_loop(struct comp_test_data *test_data, uint8_t level,
14                         enum rte_comp_xform_type type,
15                         uint8_t *output_data_ptr,
16                         size_t *output_data_sz)
17 {
18         uint8_t dev_id = test_data->cdev_id;
19         uint32_t i, iter, num_iter;
20         struct rte_comp_op **ops, **deq_ops;
21         void *priv_xform = NULL;
22         struct rte_comp_xform xform;
23         size_t output_size = 0;
24         struct rte_mbuf **input_bufs, **output_bufs;
25         int res = 0;
26         int allocated = 0;
27
28         if (test_data == NULL || !test_data->burst_sz) {
29                 RTE_LOG(ERR, USER1,
30                         "Unknown burst size\n");
31                 return -1;
32         }
33
34         ops = rte_zmalloc_socket(NULL,
35                 2 * test_data->total_bufs * sizeof(struct rte_comp_op *),
36                 0, rte_socket_id());
37
38         if (ops == NULL) {
39                 RTE_LOG(ERR, USER1,
40                         "Can't allocate memory for ops strucures\n");
41                 return -1;
42         }
43
44         deq_ops = &ops[test_data->total_bufs];
45
46         if (type == RTE_COMP_COMPRESS) {
47                 xform = (struct rte_comp_xform) {
48                         .type = RTE_COMP_COMPRESS,
49                         .compress = {
50                                 .algo = RTE_COMP_ALGO_DEFLATE,
51                                 .deflate.huffman = test_data->huffman_enc,
52                                 .level = level,
53                                 .window_size = test_data->window_sz,
54                                 .chksum = RTE_COMP_CHECKSUM_NONE,
55                                 .hash_algo = RTE_COMP_HASH_ALGO_NONE
56                         }
57                 };
58                 input_bufs = test_data->decomp_bufs;
59                 output_bufs = test_data->comp_bufs;
60         } else {
61                 xform = (struct rte_comp_xform) {
62                         .type = RTE_COMP_DECOMPRESS,
63                         .decompress = {
64                                 .algo = RTE_COMP_ALGO_DEFLATE,
65                                 .chksum = RTE_COMP_CHECKSUM_NONE,
66                                 .window_size = test_data->window_sz,
67                                 .hash_algo = RTE_COMP_HASH_ALGO_NONE
68                         }
69                 };
70                 input_bufs = test_data->comp_bufs;
71                 output_bufs = test_data->decomp_bufs;
72         }
73
74         /* Create private xform */
75         if (rte_compressdev_private_xform_create(dev_id, &xform,
76                         &priv_xform) < 0) {
77                 RTE_LOG(ERR, USER1, "Private xform could not be created\n");
78                 res = -1;
79                 goto end;
80         }
81
82         num_iter = 1;
83
84         for (iter = 0; iter < num_iter; iter++) {
85                 uint32_t total_ops = test_data->total_bufs;
86                 uint32_t remaining_ops = test_data->total_bufs;
87                 uint32_t total_deq_ops = 0;
88                 uint32_t total_enq_ops = 0;
89                 uint16_t ops_unused = 0;
90                 uint16_t num_enq = 0;
91                 uint16_t num_deq = 0;
92
93                 output_size = 0;
94
95                 while (remaining_ops > 0) {
96                         uint16_t num_ops = RTE_MIN(remaining_ops,
97                                                    test_data->burst_sz);
98                         uint16_t ops_needed = num_ops - ops_unused;
99
100                         /*
101                          * Move the unused operations from the previous
102                          * enqueue_burst call to the front, to maintain order
103                          */
104                         if ((ops_unused > 0) && (num_enq > 0)) {
105                                 size_t nb_b_to_mov =
106                                       ops_unused * sizeof(struct rte_comp_op *);
107
108                                 memmove(ops, &ops[num_enq], nb_b_to_mov);
109                         }
110
111                         /* Allocate compression operations */
112                         if (ops_needed && !rte_comp_op_bulk_alloc(
113                                                 test_data->op_pool,
114                                                 &ops[ops_unused],
115                                                 ops_needed)) {
116                                 RTE_LOG(ERR, USER1,
117                                       "Could not allocate enough operations\n");
118                                 res = -1;
119                                 goto end;
120                         }
121                         allocated += ops_needed;
122
123                         for (i = 0; i < ops_needed; i++) {
124                                 /*
125                                  * Calculate next buffer to attach to operation
126                                  */
127                                 uint32_t buf_id = total_enq_ops + i +
128                                                 ops_unused;
129                                 uint16_t op_id = ops_unused + i;
130                                 /* Reset all data in output buffers */
131                                 struct rte_mbuf *m = output_bufs[buf_id];
132
133                                 m->pkt_len = test_data->seg_sz * m->nb_segs;
134                                 while (m) {
135                                         m->data_len = m->buf_len - m->data_off;
136                                         m = m->next;
137                                 }
138                                 ops[op_id]->m_src = input_bufs[buf_id];
139                                 ops[op_id]->m_dst = output_bufs[buf_id];
140                                 ops[op_id]->src.offset = 0;
141                                 ops[op_id]->src.length =
142                                         rte_pktmbuf_pkt_len(input_bufs[buf_id]);
143                                 ops[op_id]->dst.offset = 0;
144                                 ops[op_id]->flush_flag = RTE_COMP_FLUSH_FINAL;
145                                 ops[op_id]->input_chksum = buf_id;
146                                 ops[op_id]->private_xform = priv_xform;
147                         }
148
149                         num_enq = rte_compressdev_enqueue_burst(dev_id, 0, ops,
150                                                                 num_ops);
151                         if (num_enq == 0) {
152                                 struct rte_compressdev_stats stats;
153
154                                 rte_compressdev_stats_get(dev_id, &stats);
155                                 if (stats.enqueue_err_count) {
156                                         res = -1;
157                                         goto end;
158                                 }
159                         }
160
161                         ops_unused = num_ops - num_enq;
162                         remaining_ops -= num_enq;
163                         total_enq_ops += num_enq;
164
165                         num_deq = rte_compressdev_dequeue_burst(dev_id, 0,
166                                                            deq_ops,
167                                                            test_data->burst_sz);
168                         total_deq_ops += num_deq;
169
170                         for (i = 0; i < num_deq; i++) {
171                                 struct rte_comp_op *op = deq_ops[i];
172
173                                 if (op->status != RTE_COMP_OP_STATUS_SUCCESS) {
174                                         RTE_LOG(ERR, USER1,
175                                                 "Some operations were not successful\n");
176                                         goto end;
177                                 }
178
179                                 const void *read_data_addr =
180                                                 rte_pktmbuf_read(op->m_dst, 0,
181                                                 op->produced, output_data_ptr);
182                                 if (read_data_addr == NULL) {
183                                         RTE_LOG(ERR, USER1,
184                                                 "Could not copy buffer in destination\n");
185                                         res = -1;
186                                         goto end;
187                                 }
188
189                                 if (read_data_addr != output_data_ptr)
190                                         rte_memcpy(output_data_ptr,
191                                                    rte_pktmbuf_mtod(op->m_dst,
192                                                                     uint8_t *),
193                                                    op->produced);
194                                 output_data_ptr += op->produced;
195                                 output_size += op->produced;
196
197                         }
198
199
200                         if (iter == num_iter - 1) {
201                                 for (i = 0; i < num_deq; i++) {
202                                         struct rte_comp_op *op = deq_ops[i];
203                                         struct rte_mbuf *m = op->m_dst;
204
205                                         m->pkt_len = op->produced;
206                                         uint32_t remaining_data = op->produced;
207                                         uint16_t data_to_append;
208
209                                         while (remaining_data > 0) {
210                                                 data_to_append =
211                                                         RTE_MIN(remaining_data,
212                                                              test_data->seg_sz);
213                                                 m->data_len = data_to_append;
214                                                 remaining_data -=
215                                                                 data_to_append;
216                                                 m = m->next;
217                                         }
218                                 }
219                         }
220                         rte_mempool_put_bulk(test_data->op_pool,
221                                              (void **)deq_ops, num_deq);
222                         allocated -= num_deq;
223                 }
224
225                 /* Dequeue the last operations */
226                 while (total_deq_ops < total_ops) {
227                         num_deq = rte_compressdev_dequeue_burst(dev_id, 0,
228                                                 deq_ops, test_data->burst_sz);
229                         if (num_deq == 0) {
230                                 struct rte_compressdev_stats stats;
231
232                                 rte_compressdev_stats_get(dev_id, &stats);
233                                 if (stats.dequeue_err_count) {
234                                         res = -1;
235                                         goto end;
236                                 }
237                         }
238
239                         total_deq_ops += num_deq;
240
241                         for (i = 0; i < num_deq; i++) {
242                                 struct rte_comp_op *op = deq_ops[i];
243
244                                 if (op->status != RTE_COMP_OP_STATUS_SUCCESS) {
245                                         RTE_LOG(ERR, USER1,
246                                                 "Some operations were not successful\n");
247                                         goto end;
248                                 }
249
250                                 const void *read_data_addr =
251                                                 rte_pktmbuf_read(op->m_dst,
252                                                                  op->dst.offset,
253                                                 op->produced, output_data_ptr);
254                                 if (read_data_addr == NULL) {
255                                         RTE_LOG(ERR, USER1,
256                                                 "Could not copy buffer in destination\n");
257                                         res = -1;
258                                         goto end;
259                                 }
260
261                                 if (read_data_addr != output_data_ptr)
262                                         rte_memcpy(output_data_ptr,
263                                                    rte_pktmbuf_mtod(
264                                                         op->m_dst, uint8_t *),
265                                                    op->produced);
266                                 output_data_ptr += op->produced;
267                                 output_size += op->produced;
268
269                         }
270
271                         if (iter == num_iter - 1) {
272                                 for (i = 0; i < num_deq; i++) {
273                                         struct rte_comp_op *op = deq_ops[i];
274                                         struct rte_mbuf *m = op->m_dst;
275
276                                         m->pkt_len = op->produced;
277                                         uint32_t remaining_data = op->produced;
278                                         uint16_t data_to_append;
279
280                                         while (remaining_data > 0) {
281                                                 data_to_append =
282                                                 RTE_MIN(remaining_data,
283                                                         test_data->seg_sz);
284                                                 m->data_len = data_to_append;
285                                                 remaining_data -=
286                                                                 data_to_append;
287                                                 m = m->next;
288                                         }
289                                 }
290                         }
291                         rte_mempool_put_bulk(test_data->op_pool,
292                                              (void **)deq_ops, num_deq);
293                         allocated -= num_deq;
294                 }
295         }
296
297         if (output_data_sz)
298                 *output_data_sz = output_size;
299 end:
300         rte_mempool_put_bulk(test_data->op_pool, (void **)ops, allocated);
301         rte_compressdev_private_xform_free(dev_id, priv_xform);
302         rte_free(ops);
303         return res;
304 }
305
306
307
308 int
309 cperf_verification(struct comp_test_data *test_data, uint8_t level)
310 {
311         int ret = EXIT_SUCCESS;
312
313         test_data->ratio = 0;
314
315         if (main_loop(test_data, level, RTE_COMP_COMPRESS,
316                       test_data->compressed_data,
317                       &test_data->comp_data_sz) < 0) {
318                 ret = EXIT_FAILURE;
319                 goto end;
320         }
321
322         if (main_loop(test_data, level, RTE_COMP_DECOMPRESS,
323                       test_data->decompressed_data,
324                       &test_data->decomp_data_sz) < 0) {
325                 ret = EXIT_FAILURE;
326                 goto end;
327         }
328
329         if (test_data->decomp_data_sz != test_data->input_data_sz) {
330                 RTE_LOG(ERR, USER1,
331            "Decompressed data length not equal to input data length\n");
332                 RTE_LOG(ERR, USER1,
333                         "Decompressed size = %zu, expected = %zu\n",
334                         test_data->decomp_data_sz, test_data->input_data_sz);
335                 ret = EXIT_FAILURE;
336                 goto end;
337         } else {
338                 if (memcmp(test_data->decompressed_data,
339                                 test_data->input_data,
340                                 test_data->input_data_sz) != 0) {
341                         RTE_LOG(ERR, USER1,
342                     "Decompressed data is not the same as file data\n");
343                         ret = EXIT_FAILURE;
344                         goto end;
345                 }
346         }
347
348         test_data->ratio = (double) test_data->comp_data_sz /
349                         test_data->input_data_sz * 100;
350
351 end:
352         return ret;
353 }