Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Intel Corporation
3 : : */
4 : :
5 : : #include <getopt.h>
6 : : #include <stdint.h>
7 : : #include <stdio.h>
8 : : #include <string.h>
9 : : #include <inttypes.h>
10 : : #include <stdlib.h>
11 : : #include <errno.h>
12 : :
13 : : #include <rte_string_fns.h>
14 : : #include <rte_comp.h>
15 : :
16 : : #include "comp_perf_options.h"
17 : :
18 : : #define CPERF_PTEST_TYPE ("ptest")
19 : : #define CPERF_DRIVER_NAME ("driver-name")
20 : : #define CPERF_TEST_FILE ("input-file")
21 : : #define CPERF_SEG_SIZE ("seg-sz")
22 : : #define CPERF_BURST_SIZE ("burst-sz")
23 : : #define CPERF_EXTENDED_SIZE ("extended-input-sz")
24 : : #define CPERF_POOL_SIZE ("pool-sz")
25 : : #define CPERF_MAX_SGL_SEGS ("max-num-sgl-segs")
26 : : #define CPERF_NUM_ITER ("num-iter")
27 : : #define CPERF_OPTYPE ("operation")
28 : : #define CPERF_ALGO ("algo")
29 : : #define CPERF_HUFFMAN_ENC ("huffman-enc")
30 : : #define CPERF_LZ4_FLAGS ("lz4-flags")
31 : : #define CPERF_LEVEL ("compress-level")
32 : : #define CPERF_WINDOW_SIZE ("window-sz")
33 : : #define CPERF_EXTERNAL_MBUFS ("external-mbufs")
34 : : #define CPERF_DICTIONARY ("dictionary")
35 : :
36 : : /* cyclecount-specific options */
37 : : #define CPERF_CYCLECOUNT_DELAY_US ("cc-delay-us")
38 : :
39 : : struct name_id_map {
40 : : const char *name;
41 : : uint32_t id;
42 : : };
43 : :
44 : : static void
45 : : usage(char *progname)
46 : : {
47 : : printf("%s [EAL options] --\n"
48 : : " --ptest throughput / verify / pmd-cyclecount\n"
49 : : " --driver-name NAME: compress driver to use\n"
50 : : " --input-file NAME: file to compress and decompress\n"
51 : : " --extended-input-sz N: extend file data up to this size (default: no extension)\n"
52 : : " --seg-sz N: size of segment to store the data (default: 2048)\n"
53 : : " --burst-sz N: compress operation burst size\n"
54 : : " --pool-sz N: mempool size for compress operations/mbufs\n"
55 : : " (default: 8192)\n"
56 : : " --max-num-sgl-segs N: maximum number of segments for each mbuf\n"
57 : : " (default: 16)\n"
58 : : " --num-iter N: number of times the file will be\n"
59 : : " compressed/decompressed (default: 10000)\n"
60 : : " --operation [comp/decomp/comp_and_decomp]: perform test on\n"
61 : : " compression, decompression or both operations\n"
62 : : " --algo [null/deflate/lzs/lz4]: perform test on algorithm\n"
63 : : " null(DMA), deflate, lzs or lz4 (default: deflate)\n"
64 : : " --huffman-enc [fixed/dynamic/default]: Huffman encoding\n"
65 : : " (default: dynamic)\n"
66 : : " --lz4-flags N: flags to configure LZ4 algorithm (default: 0)\n"
67 : : " --compress-level N: compression level, which could be a single value, list or range\n"
68 : : " (default: range between 1 and 9)\n"
69 : : " --window-sz N: base two log value of compression window size\n"
70 : : " (e.g.: 15 => 32k, default: max supported by PMD)\n"
71 : : " --external-mbufs: use memzones as external buffers instead of\n"
72 : : " keeping the data directly in mbuf area\n"
73 : : " --cc-delay-us N: delay between enqueue and dequeue operations in microseconds\n"
74 : : " valid only for cyclecount perf test (default: 500 us)\n"
75 : : " --dictionary NAME: file with dictionary\n"
76 : : " -h: prints this help\n",
77 : : progname);
78 : : }
79 : :
80 : : static int
81 : 0 : get_str_key_id_mapping(struct name_id_map *map, unsigned int map_len,
82 : : const char *str_key)
83 : : {
84 : : unsigned int i;
85 : :
86 : 0 : for (i = 0; i < map_len; i++) {
87 : :
88 : 0 : if (strcmp(str_key, map[i].name) == 0)
89 : 0 : return map[i].id;
90 : : }
91 : :
92 : : return -1;
93 : : }
94 : :
95 : : static int
96 : 0 : parse_cperf_test_type(struct comp_test_data *test_data, const char *arg)
97 : : {
98 : 0 : struct name_id_map cperftest_namemap[] = {
99 : : {
100 : 0 : comp_perf_test_type_strs[CPERF_TEST_TYPE_THROUGHPUT],
101 : : CPERF_TEST_TYPE_THROUGHPUT
102 : : },
103 : : {
104 : 0 : comp_perf_test_type_strs[CPERF_TEST_TYPE_VERIFY],
105 : : CPERF_TEST_TYPE_VERIFY
106 : : },
107 : : {
108 : 0 : comp_perf_test_type_strs[CPERF_TEST_TYPE_PMDCC],
109 : : CPERF_TEST_TYPE_PMDCC
110 : : }
111 : : };
112 : :
113 : 0 : int id = get_str_key_id_mapping(
114 : : (struct name_id_map *)cperftest_namemap,
115 : : RTE_DIM(cperftest_namemap), arg);
116 : 0 : if (id < 0) {
117 : 0 : RTE_LOG(ERR, USER1, "failed to parse test type");
118 : 0 : return -1;
119 : : }
120 : :
121 : 0 : test_data->test = (enum cperf_test_type)id;
122 : :
123 : 0 : return 0;
124 : : }
125 : :
126 : : static int
127 : 0 : parse_uint32_t(uint32_t *value, const char *arg)
128 : : {
129 : 0 : char *end = NULL;
130 : 0 : unsigned long n = strtoul(arg, &end, 10);
131 : :
132 : 0 : if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
133 : : return -1;
134 : :
135 : 0 : if (n > UINT32_MAX)
136 : : return -ERANGE;
137 : :
138 : 0 : *value = (uint32_t) n;
139 : :
140 : 0 : return 0;
141 : : }
142 : :
143 : : static int
144 : : parse_uint16_t(uint16_t *value, const char *arg)
145 : : {
146 : 0 : uint32_t val = 0;
147 : 0 : int ret = parse_uint32_t(&val, arg);
148 : :
149 : 0 : if (ret < 0)
150 : : return ret;
151 : :
152 : 0 : if (val > UINT16_MAX)
153 : : return -ERANGE;
154 : :
155 : 0 : *value = (uint16_t) val;
156 : :
157 : : return 0;
158 : : }
159 : :
160 : : static int
161 : : parse_uint8_t(uint8_t *value, const char *arg)
162 : : {
163 : 0 : uint32_t val = 0;
164 : 0 : int ret = parse_uint32_t(&val, arg);
165 : :
166 : 0 : if (ret < 0)
167 : : return ret;
168 : :
169 : 0 : if (val > UINT8_MAX)
170 : : return -ERANGE;
171 : :
172 : 0 : *value = (uint8_t) val;
173 : :
174 : : return 0;
175 : : }
176 : :
177 : : static int
178 : 0 : parse_range(const char *arg, uint8_t *min, uint8_t *max, uint8_t *inc)
179 : : {
180 : : char *token;
181 : : uint8_t number;
182 : :
183 : 0 : char *copy_arg = strdup(arg);
184 : :
185 : 0 : if (copy_arg == NULL)
186 : : return -1;
187 : :
188 : 0 : errno = 0;
189 : 0 : token = strtok(copy_arg, ":");
190 : :
191 : : /* Parse minimum value */
192 : 0 : if (token != NULL) {
193 : 0 : number = strtoul(token, NULL, 10);
194 : :
195 : 0 : if (errno == EINVAL || errno == ERANGE)
196 : 0 : goto err_range;
197 : :
198 : 0 : *min = number;
199 : : } else
200 : 0 : goto err_range;
201 : :
202 : 0 : token = strtok(NULL, ":");
203 : :
204 : : /* Parse increment value */
205 : 0 : if (token != NULL) {
206 : 0 : number = strtoul(token, NULL, 10);
207 : :
208 : 0 : if (errno == EINVAL || errno == ERANGE ||
209 : : number == 0)
210 : 0 : goto err_range;
211 : :
212 : 0 : *inc = number;
213 : : } else
214 : 0 : goto err_range;
215 : :
216 : 0 : token = strtok(NULL, ":");
217 : :
218 : : /* Parse maximum value */
219 : 0 : if (token != NULL) {
220 : 0 : number = strtoul(token, NULL, 10);
221 : :
222 : 0 : if (errno == EINVAL || errno == ERANGE ||
223 : 0 : number < *min)
224 : 0 : goto err_range;
225 : :
226 : 0 : *max = number;
227 : : } else
228 : 0 : goto err_range;
229 : :
230 : 0 : if (strtok(NULL, ":") != NULL)
231 : 0 : goto err_range;
232 : :
233 : 0 : free(copy_arg);
234 : 0 : return 0;
235 : :
236 : 0 : err_range:
237 : 0 : free(copy_arg);
238 : 0 : return -1;
239 : : }
240 : :
241 : : static int
242 : 0 : parse_list(const char *arg, uint8_t *list, uint8_t *min, uint8_t *max)
243 : : {
244 : : char *token;
245 : : uint32_t number;
246 : : uint8_t count = 0;
247 : : uint32_t temp_min;
248 : : uint32_t temp_max;
249 : :
250 : 0 : char *copy_arg = strdup(arg);
251 : :
252 : 0 : if (copy_arg == NULL)
253 : : return -1;
254 : :
255 : 0 : errno = 0;
256 : 0 : token = strtok(copy_arg, ",");
257 : :
258 : : /* Parse first value */
259 : 0 : if (token != NULL) {
260 : 0 : number = strtoul(token, NULL, 10);
261 : :
262 : 0 : if (errno == EINVAL || errno == ERANGE)
263 : 0 : goto err_list;
264 : :
265 : 0 : list[count++] = number;
266 : : temp_min = number;
267 : : temp_max = number;
268 : : } else
269 : 0 : goto err_list;
270 : :
271 : 0 : token = strtok(NULL, ",");
272 : :
273 : 0 : while (token != NULL) {
274 : 0 : if (count == MAX_LIST) {
275 : 0 : RTE_LOG(WARNING, USER1,
276 : : "Using only the first %u sizes\n",
277 : : MAX_LIST);
278 : 0 : break;
279 : : }
280 : :
281 : 0 : number = strtoul(token, NULL, 10);
282 : :
283 : 0 : if (errno == EINVAL || errno == ERANGE)
284 : 0 : goto err_list;
285 : :
286 : 0 : list[count++] = number;
287 : :
288 : : if (number < temp_min)
289 : : temp_min = number;
290 : : if (number > temp_max)
291 : : temp_max = number;
292 : :
293 : 0 : token = strtok(NULL, ",");
294 : : }
295 : :
296 : 0 : if (min)
297 : 0 : *min = temp_min;
298 : 0 : if (max)
299 : 0 : *max = temp_max;
300 : :
301 : 0 : free(copy_arg);
302 : 0 : return count;
303 : :
304 : 0 : err_list:
305 : 0 : free(copy_arg);
306 : 0 : return -1;
307 : : }
308 : :
309 : : static int
310 : 0 : parse_num_iter(struct comp_test_data *test_data, const char *arg)
311 : : {
312 : 0 : int ret = parse_uint32_t(&test_data->num_iter, arg);
313 : :
314 : 0 : if (ret) {
315 : 0 : RTE_LOG(ERR, USER1, "Failed to parse total iteration count\n");
316 : 0 : return -1;
317 : : }
318 : :
319 : 0 : if (test_data->num_iter == 0) {
320 : 0 : RTE_LOG(ERR, USER1,
321 : : "Total number of iterations must be higher than 0\n");
322 : 0 : return -1;
323 : : }
324 : :
325 : : return ret;
326 : : }
327 : :
328 : : static int
329 : 0 : parse_pool_sz(struct comp_test_data *test_data, const char *arg)
330 : : {
331 : 0 : int ret = parse_uint32_t(&test_data->pool_sz, arg);
332 : :
333 : 0 : if (ret) {
334 : 0 : RTE_LOG(ERR, USER1, "Failed to parse pool size");
335 : 0 : return -1;
336 : : }
337 : :
338 : 0 : if (test_data->pool_sz == 0) {
339 : 0 : RTE_LOG(ERR, USER1, "Pool size must be higher than 0\n");
340 : 0 : return -1;
341 : : }
342 : :
343 : : return ret;
344 : : }
345 : :
346 : : static int
347 : 0 : parse_burst_sz(struct comp_test_data *test_data, const char *arg)
348 : : {
349 : : int ret = parse_uint16_t(&test_data->burst_sz, arg);
350 : :
351 : : if (ret) {
352 : 0 : RTE_LOG(ERR, USER1, "Failed to parse burst size/s\n");
353 : 0 : return -1;
354 : : }
355 : :
356 : 0 : if (test_data->burst_sz == 0) {
357 : 0 : RTE_LOG(ERR, USER1, "Burst size must be higher than 0\n");
358 : 0 : return -1;
359 : : }
360 : :
361 : : return 0;
362 : : }
363 : :
364 : : static int
365 : 0 : parse_extended_input_sz(struct comp_test_data *test_data, const char *arg)
366 : : {
367 : : uint32_t tmp;
368 : 0 : int ret = parse_uint32_t(&tmp, arg);
369 : :
370 : 0 : if (ret) {
371 : 0 : RTE_LOG(ERR, USER1, "Failed to parse extended input size\n");
372 : 0 : return -1;
373 : : }
374 : 0 : test_data->input_data_sz = tmp;
375 : :
376 : 0 : if (tmp == 0) {
377 : 0 : RTE_LOG(ERR, USER1,
378 : : "Extended file size must be higher than 0\n");
379 : 0 : return -1;
380 : : }
381 : : return 0;
382 : : }
383 : :
384 : : static int
385 : 0 : parse_seg_sz(struct comp_test_data *test_data, const char *arg)
386 : : {
387 : : int ret = parse_uint16_t(&test_data->seg_sz, arg);
388 : :
389 : : if (ret) {
390 : 0 : RTE_LOG(ERR, USER1, "Failed to parse segment size\n");
391 : 0 : return -1;
392 : : }
393 : :
394 : 0 : if (test_data->seg_sz < MIN_COMPRESSED_BUF_SIZE) {
395 : 0 : RTE_LOG(ERR, USER1, "Segment size must be higher than %d\n",
396 : : MIN_COMPRESSED_BUF_SIZE - 1);
397 : 0 : return -1;
398 : : }
399 : :
400 : 0 : if (test_data->seg_sz > MAX_SEG_SIZE) {
401 : 0 : RTE_LOG(ERR, USER1, "Segment size must be lower than %d\n",
402 : : MAX_SEG_SIZE + 1);
403 : 0 : return -1;
404 : : }
405 : :
406 : : return 0;
407 : : }
408 : :
409 : : static int
410 : 0 : parse_max_num_sgl_segs(struct comp_test_data *test_data, const char *arg)
411 : : {
412 : : int ret = parse_uint16_t(&test_data->max_sgl_segs, arg);
413 : :
414 : : if (ret) {
415 : 0 : RTE_LOG(ERR, USER1,
416 : : "Failed to parse max number of segments per mbuf chain\n");
417 : 0 : return -1;
418 : : }
419 : :
420 : 0 : if (test_data->max_sgl_segs == 0) {
421 : 0 : RTE_LOG(ERR, USER1, "Max number of segments per mbuf chain "
422 : : "must be higher than 0\n");
423 : 0 : return -1;
424 : : }
425 : :
426 : : return 0;
427 : : }
428 : :
429 : : static int
430 : 0 : parse_window_sz(struct comp_test_data *test_data, const char *arg)
431 : : {
432 : : uint16_t tmp;
433 : : int ret = parse_uint16_t(&tmp, arg);
434 : :
435 : : if (ret) {
436 : 0 : RTE_LOG(ERR, USER1, "Failed to parse window size\n");
437 : 0 : return -1;
438 : : }
439 : 0 : test_data->window_sz = (int)tmp;
440 : :
441 : 0 : return 0;
442 : : }
443 : :
444 : : static int
445 : 0 : parse_driver_name(struct comp_test_data *test_data, const char *arg)
446 : : {
447 : 0 : if (strlen(arg) > (sizeof(test_data->driver_name) - 1))
448 : : return -1;
449 : :
450 : 0 : strlcpy(test_data->driver_name, arg,
451 : : sizeof(test_data->driver_name));
452 : :
453 : 0 : return 0;
454 : : }
455 : :
456 : : static int
457 : 0 : parse_test_file(struct comp_test_data *test_data, const char *arg)
458 : : {
459 : 0 : if (strlen(arg) > (sizeof(test_data->input_file) - 1))
460 : : return -1;
461 : :
462 : 0 : strlcpy(test_data->input_file, arg, sizeof(test_data->input_file));
463 : :
464 : 0 : return 0;
465 : : }
466 : :
467 : : static int
468 : 0 : parse_op_type(struct comp_test_data *test_data, const char *arg)
469 : : {
470 : 0 : struct name_id_map optype_namemap[] = {
471 : : {
472 : : "comp",
473 : : COMPRESS
474 : : },
475 : : {
476 : : "decomp",
477 : : DECOMPRESS
478 : : },
479 : : {
480 : : "comp_and_decomp",
481 : : COMPRESS_DECOMPRESS
482 : : }
483 : : };
484 : :
485 : 0 : int id = get_str_key_id_mapping(optype_namemap,
486 : : RTE_DIM(optype_namemap), arg);
487 : 0 : if (id < 0) {
488 : 0 : RTE_LOG(ERR, USER1, "Invalid operation type specified\n");
489 : 0 : return -1;
490 : : }
491 : :
492 : 0 : test_data->test_op = (enum comp_operation)id;
493 : :
494 : 0 : return 0;
495 : : }
496 : :
497 : : static int
498 : 0 : parse_algo(struct comp_test_data *test_data, const char *arg)
499 : : {
500 : 0 : struct name_id_map algo_namemap[] = {
501 : : {
502 : : "null",
503 : : RTE_COMP_ALGO_NULL
504 : : },
505 : : {
506 : : "deflate",
507 : : RTE_COMP_ALGO_DEFLATE
508 : : },
509 : : {
510 : : "lzs",
511 : : RTE_COMP_ALGO_LZS
512 : : },
513 : : {
514 : : "lz4",
515 : : RTE_COMP_ALGO_LZ4
516 : : }
517 : : };
518 : :
519 : 0 : int id = get_str_key_id_mapping(algo_namemap,
520 : : RTE_DIM(algo_namemap), arg);
521 : 0 : if (id < 0) {
522 : 0 : RTE_LOG(ERR, USER1, "Invalid algorithm specified\n");
523 : 0 : return -1;
524 : : }
525 : :
526 : 0 : test_data->test_algo = (enum rte_comp_algorithm)id;
527 : :
528 : 0 : return 0;
529 : : }
530 : :
531 : : static int
532 : 0 : parse_huffman_enc(struct comp_test_data *test_data, const char *arg)
533 : : {
534 : 0 : struct name_id_map huffman_namemap[] = {
535 : : {
536 : : "default",
537 : : RTE_COMP_HUFFMAN_DEFAULT
538 : : },
539 : : {
540 : : "fixed",
541 : : RTE_COMP_HUFFMAN_FIXED
542 : : },
543 : : {
544 : : "dynamic",
545 : : RTE_COMP_HUFFMAN_DYNAMIC
546 : : }
547 : : };
548 : :
549 : 0 : int id = get_str_key_id_mapping(huffman_namemap,
550 : : RTE_DIM(huffman_namemap), arg);
551 : 0 : if (id < 0) {
552 : 0 : RTE_LOG(ERR, USER1, "Invalid Huffman encoding specified\n");
553 : 0 : return -1;
554 : : }
555 : :
556 : 0 : test_data->huffman_enc = (enum rte_comp_huffman)id;
557 : :
558 : 0 : return 0;
559 : : }
560 : :
561 : : static int
562 : 0 : parse_lz4_flags(struct comp_test_data *test_data, const char *arg)
563 : : {
564 : : int ret = parse_uint8_t(&test_data->lz4_flags, arg);
565 : :
566 : : if (ret) {
567 : 0 : RTE_LOG(ERR, USER1, "Failed to parse LZ4 flags\n");
568 : 0 : return -1;
569 : : }
570 : :
571 : : return 0;
572 : : }
573 : :
574 : : static int
575 : 0 : parse_level(struct comp_test_data *test_data, const char *arg)
576 : : {
577 : : int ret;
578 : :
579 : : /*
580 : : * Try parsing the argument as a range, if it fails,
581 : : * parse it as a list
582 : : */
583 : 0 : if (parse_range(arg, &test_data->level_lst.min,
584 : : &test_data->level_lst.max,
585 : : &test_data->level_lst.inc) < 0) {
586 : 0 : ret = parse_list(arg, test_data->level_lst.list,
587 : : &test_data->level_lst.min,
588 : : &test_data->level_lst.max);
589 : 0 : if (ret < 0) {
590 : 0 : RTE_LOG(ERR, USER1,
591 : : "Failed to parse compression level/s\n");
592 : 0 : return -1;
593 : : }
594 : 0 : test_data->level_lst.count = ret;
595 : :
596 : 0 : if (test_data->level_lst.max > RTE_COMP_LEVEL_MAX) {
597 : 0 : RTE_LOG(ERR, USER1, "Level cannot be higher than %u\n",
598 : : RTE_COMP_LEVEL_MAX);
599 : 0 : return -1;
600 : : }
601 : : }
602 : :
603 : : return 0;
604 : : }
605 : :
606 : : static int
607 : 0 : parse_external_mbufs(struct comp_test_data *test_data,
608 : : const char *arg __rte_unused)
609 : : {
610 : 0 : test_data->use_external_mbufs = 1;
611 : 0 : return 0;
612 : : }
613 : :
614 : : static int
615 : 0 : parse_dictionary_file(struct comp_test_data *test_data, const char *arg)
616 : : {
617 : 0 : if (strlen(arg) > (sizeof(test_data->dictionary_file) - 1))
618 : : return -1;
619 : :
620 : 0 : strlcpy(test_data->dictionary_file, arg, sizeof(test_data->dictionary_file));
621 : :
622 : 0 : return 0;
623 : : }
624 : :
625 : : static int
626 : 0 : parse_cyclecount_delay_us(struct comp_test_data *test_data,
627 : : const char *arg)
628 : : {
629 : 0 : int ret = parse_uint32_t(&(test_data->cyclecount_delay), arg);
630 : :
631 : 0 : if (ret) {
632 : 0 : RTE_LOG(ERR, USER1, "Failed to parse cyclecount delay\n");
633 : 0 : return -1;
634 : : }
635 : : return 0;
636 : : }
637 : :
638 : : typedef int (*option_parser_t)(struct comp_test_data *test_data,
639 : : const char *arg);
640 : :
641 : : struct long_opt_parser {
642 : : const char *lgopt_name;
643 : : option_parser_t parser_fn;
644 : : };
645 : :
646 : : static struct option lgopts[] = {
647 : : { CPERF_PTEST_TYPE, required_argument, 0, 0 },
648 : : { CPERF_DRIVER_NAME, required_argument, 0, 0 },
649 : : { CPERF_TEST_FILE, required_argument, 0, 0 },
650 : : { CPERF_SEG_SIZE, required_argument, 0, 0 },
651 : : { CPERF_BURST_SIZE, required_argument, 0, 0 },
652 : : { CPERF_EXTENDED_SIZE, required_argument, 0, 0 },
653 : : { CPERF_POOL_SIZE, required_argument, 0, 0 },
654 : : { CPERF_MAX_SGL_SEGS, required_argument, 0, 0},
655 : : { CPERF_NUM_ITER, required_argument, 0, 0 },
656 : : { CPERF_OPTYPE, required_argument, 0, 0 },
657 : : { CPERF_ALGO, required_argument, 0, 0 },
658 : : { CPERF_HUFFMAN_ENC, required_argument, 0, 0 },
659 : : { CPERF_LZ4_FLAGS, required_argument, 0, 0 },
660 : : { CPERF_LEVEL, required_argument, 0, 0 },
661 : : { CPERF_WINDOW_SIZE, required_argument, 0, 0 },
662 : : { CPERF_EXTERNAL_MBUFS, 0, 0, 0 },
663 : : { CPERF_DICTIONARY, required_argument, 0, 0 },
664 : : { CPERF_CYCLECOUNT_DELAY_US, required_argument, 0, 0 },
665 : : { NULL, 0, 0, 0 }
666 : : };
667 : :
668 : : static int
669 : 0 : comp_perf_opts_parse_long(int opt_idx, struct comp_test_data *test_data)
670 : : {
671 : 0 : struct long_opt_parser parsermap[] = {
672 : : { CPERF_PTEST_TYPE, parse_cperf_test_type },
673 : : { CPERF_DRIVER_NAME, parse_driver_name },
674 : : { CPERF_TEST_FILE, parse_test_file },
675 : : { CPERF_SEG_SIZE, parse_seg_sz },
676 : : { CPERF_BURST_SIZE, parse_burst_sz },
677 : : { CPERF_EXTENDED_SIZE, parse_extended_input_sz },
678 : : { CPERF_POOL_SIZE, parse_pool_sz },
679 : : { CPERF_MAX_SGL_SEGS, parse_max_num_sgl_segs },
680 : : { CPERF_NUM_ITER, parse_num_iter },
681 : : { CPERF_OPTYPE, parse_op_type },
682 : : { CPERF_ALGO, parse_algo },
683 : : { CPERF_HUFFMAN_ENC, parse_huffman_enc },
684 : : { CPERF_LZ4_FLAGS, parse_lz4_flags },
685 : : { CPERF_LEVEL, parse_level },
686 : : { CPERF_WINDOW_SIZE, parse_window_sz },
687 : : { CPERF_EXTERNAL_MBUFS, parse_external_mbufs },
688 : : { CPERF_DICTIONARY, parse_dictionary_file },
689 : : { CPERF_CYCLECOUNT_DELAY_US, parse_cyclecount_delay_us },
690 : : };
691 : : unsigned int i;
692 : :
693 : 0 : for (i = 0; i < RTE_DIM(parsermap); i++) {
694 : 0 : if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
695 : : strlen(lgopts[opt_idx].name)) == 0)
696 : 0 : return parsermap[i].parser_fn(test_data, optarg);
697 : : }
698 : :
699 : : return -EINVAL;
700 : : }
701 : :
702 : : int
703 : 0 : comp_perf_options_parse(struct comp_test_data *test_data, int argc, char **argv)
704 : : {
705 : : int opt, retval, opt_idx;
706 : :
707 : 0 : while ((opt = getopt_long(argc, argv, "h", lgopts, &opt_idx)) != EOF) {
708 : 0 : switch (opt) {
709 : 0 : case 'h':
710 : 0 : usage(argv[0]);
711 : 0 : exit(EXIT_SUCCESS);
712 : : break;
713 : : /* long options */
714 : 0 : case 0:
715 : 0 : retval = comp_perf_opts_parse_long(opt_idx, test_data);
716 : 0 : if (retval != 0)
717 : 0 : return retval;
718 : :
719 : : break;
720 : :
721 : 0 : default:
722 : 0 : usage(argv[0]);
723 : 0 : return -EINVAL;
724 : : }
725 : : }
726 : :
727 : : return 0;
728 : : }
729 : :
730 : : void
731 : 0 : comp_perf_options_default(struct comp_test_data *test_data)
732 : : {
733 : 0 : test_data->seg_sz = 2048;
734 : 0 : test_data->burst_sz = 32;
735 : 0 : test_data->pool_sz = 8192;
736 : 0 : test_data->max_sgl_segs = 16;
737 : 0 : test_data->num_iter = 10000;
738 : 0 : test_data->lz4_flags = 0;
739 : 0 : test_data->huffman_enc = RTE_COMP_HUFFMAN_DYNAMIC;
740 : 0 : test_data->test_op = COMPRESS_DECOMPRESS;
741 : 0 : test_data->test_algo = RTE_COMP_ALGO_DEFLATE;
742 : 0 : test_data->window_sz = -1;
743 : 0 : test_data->level_lst.min = RTE_COMP_LEVEL_MIN;
744 : 0 : test_data->level_lst.max = RTE_COMP_LEVEL_MAX;
745 : 0 : test_data->level_lst.inc = 1;
746 : 0 : test_data->test = CPERF_TEST_TYPE_THROUGHPUT;
747 : 0 : test_data->use_external_mbufs = 0;
748 : 0 : test_data->cyclecount_delay = 500;
749 : 0 : }
750 : :
751 : : int
752 : 0 : comp_perf_options_check(struct comp_test_data *test_data)
753 : : {
754 : 0 : if (test_data->driver_name[0] == '\0') {
755 : 0 : RTE_LOG(ERR, USER1, "Driver name has to be set\n");
756 : 0 : return -1;
757 : : }
758 : :
759 : 0 : if (test_data->input_file[0] == '\0') {
760 : 0 : RTE_LOG(ERR, USER1, "Input file name has to be set\n");
761 : 0 : return -1;
762 : : }
763 : :
764 : : return 0;
765 : : }
|