xref: /dpdk/app/test-compress-perf/comp_perf_test_verify.c (revision 25d11a86c56d50947af33d0b79ede622809bd8b9)
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 }
354