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