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