ac3884a371dd89fbc4b4c0f2bdda1ea06ae4e438
[dpdk.git] / lib / librte_eal / common / eal_common_options.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #ifndef RTE_EXEC_ENV_WINDOWS
10 #include <syslog.h>
11 #endif
12 #include <ctype.h>
13 #include <limits.h>
14 #include <errno.h>
15 #include <getopt.h>
16 #ifndef RTE_EXEC_ENV_WINDOWS
17 #include <dlfcn.h>
18 #include <libgen.h>
19 #endif
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #ifndef RTE_EXEC_ENV_WINDOWS
23 #include <dirent.h>
24 #endif
25
26 #include <rte_string_fns.h>
27 #include <rte_eal.h>
28 #include <rte_log.h>
29 #include <rte_lcore.h>
30 #include <rte_memory.h>
31 #include <rte_tailq.h>
32 #include <rte_version.h>
33 #include <rte_devargs.h>
34 #include <rte_memcpy.h>
35 #ifndef RTE_EXEC_ENV_WINDOWS
36 #include <rte_telemetry.h>
37 #endif
38 #include <rte_vect.h>
39
40 #include "eal_internal_cfg.h"
41 #include "eal_options.h"
42 #include "eal_filesystem.h"
43 #include "eal_private.h"
44 #ifndef RTE_EXEC_ENV_WINDOWS
45 #include "eal_trace.h"
46 #endif
47
48 #define BITS_PER_HEX 4
49 #define LCORE_OPT_LST 1
50 #define LCORE_OPT_MSK 2
51 #define LCORE_OPT_MAP 3
52
53 const char
54 eal_short_options[] =
55         "a:" /* allow */
56         "b:" /* block */
57         "c:" /* coremask */
58         "s:" /* service coremask */
59         "d:" /* driver */
60         "h"  /* help */
61         "l:" /* corelist */
62         "S:" /* service corelist */
63         "m:" /* memory size */
64         "n:" /* memory channels */
65         "r:" /* memory ranks */
66         "v"  /* version */
67         "w:" /* pci-whitelist (deprecated) */
68         ;
69
70 const struct option
71 eal_long_options[] = {
72         {OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
73         {OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
74         {OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
75         {OPT_HELP,              0, NULL, OPT_HELP_NUM             },
76         {OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
77         {OPT_HUGE_UNLINK,       0, NULL, OPT_HUGE_UNLINK_NUM      },
78         {OPT_IOVA_MODE,         1, NULL, OPT_IOVA_MODE_NUM        },
79         {OPT_LCORES,            1, NULL, OPT_LCORES_NUM           },
80         {OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
81         {OPT_TRACE,             1, NULL, OPT_TRACE_NUM            },
82         {OPT_TRACE_DIR,         1, NULL, OPT_TRACE_DIR_NUM        },
83         {OPT_TRACE_BUF_SIZE,    1, NULL, OPT_TRACE_BUF_SIZE_NUM   },
84         {OPT_TRACE_MODE,        1, NULL, OPT_TRACE_MODE_NUM       },
85         {OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
86         {OPT_MAIN_LCORE,        1, NULL, OPT_MAIN_LCORE_NUM       },
87         {OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
88         {OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
89         {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
90         {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
91         {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
92         {OPT_IN_MEMORY,         0, NULL, OPT_IN_MEMORY_NUM        },
93         {OPT_DEV_BLOCK,         1, NULL, OPT_DEV_BLOCK_NUM        },
94         {OPT_DEV_ALLOW,         1, NULL, OPT_DEV_ALLOW_NUM        },
95         {OPT_PROC_TYPE,         1, NULL, OPT_PROC_TYPE_NUM        },
96         {OPT_SOCKET_MEM,        1, NULL, OPT_SOCKET_MEM_NUM       },
97         {OPT_SOCKET_LIMIT,      1, NULL, OPT_SOCKET_LIMIT_NUM     },
98         {OPT_SYSLOG,            1, NULL, OPT_SYSLOG_NUM           },
99         {OPT_VDEV,              1, NULL, OPT_VDEV_NUM             },
100         {OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
101         {OPT_VFIO_VF_TOKEN,     1, NULL, OPT_VFIO_VF_TOKEN_NUM    },
102         {OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
103         {OPT_LEGACY_MEM,        0, NULL, OPT_LEGACY_MEM_NUM       },
104         {OPT_SINGLE_FILE_SEGMENTS, 0, NULL, OPT_SINGLE_FILE_SEGMENTS_NUM},
105         {OPT_MATCH_ALLOCATIONS, 0, NULL, OPT_MATCH_ALLOCATIONS_NUM},
106         {OPT_TELEMETRY,         0, NULL, OPT_TELEMETRY_NUM        },
107         {OPT_NO_TELEMETRY,      0, NULL, OPT_NO_TELEMETRY_NUM     },
108         {OPT_FORCE_MAX_SIMD_BITWIDTH, 1, NULL, OPT_FORCE_MAX_SIMD_BITWIDTH_NUM},
109
110         /* legacy options that will be removed in future */
111         {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
112         {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
113
114         {0,                     0, NULL, 0                        }
115 };
116
117 TAILQ_HEAD(shared_driver_list, shared_driver);
118
119 /* Definition for shared object drivers. */
120 struct shared_driver {
121         TAILQ_ENTRY(shared_driver) next;
122
123         char    name[PATH_MAX];
124         void*   lib_handle;
125 };
126
127 /* List of external loadable drivers */
128 static struct shared_driver_list solib_list =
129 TAILQ_HEAD_INITIALIZER(solib_list);
130
131 #ifndef RTE_EXEC_ENV_WINDOWS
132 /* Default path of external loadable drivers */
133 static const char *default_solib_dir = RTE_EAL_PMD_PATH;
134 #endif
135
136 /*
137  * Stringified version of solib path used by dpdk-pmdinfo.py
138  * Note: PLEASE DO NOT ALTER THIS without making a corresponding
139  * change to usertools/dpdk-pmdinfo.py
140  */
141 static const char dpdk_solib_path[] __rte_used =
142 "DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH;
143
144 TAILQ_HEAD(device_option_list, device_option);
145
146 struct device_option {
147         TAILQ_ENTRY(device_option) next;
148
149         enum rte_devtype type;
150         char arg[];
151 };
152
153 static struct device_option_list devopt_list =
154 TAILQ_HEAD_INITIALIZER(devopt_list);
155
156 static int main_lcore_parsed;
157 static int mem_parsed;
158 static int core_parsed;
159
160 /* Allow the application to print its usage message too if set */
161 static rte_usage_hook_t rte_application_usage_hook;
162
163 /* Returns rte_usage_hook_t */
164 rte_usage_hook_t
165 eal_get_application_usage_hook(void)
166 {
167         return rte_application_usage_hook;
168 }
169
170 /* Set a per-application usage message */
171 rte_usage_hook_t
172 rte_set_application_usage_hook(rte_usage_hook_t usage_func)
173 {
174         rte_usage_hook_t old_func;
175
176         /* Will be NULL on the first call to denote the last usage routine. */
177         old_func = rte_application_usage_hook;
178         rte_application_usage_hook = usage_func;
179
180         return old_func;
181 }
182
183 #ifndef RTE_EXEC_ENV_WINDOWS
184 static char **eal_args;
185 static char **eal_app_args;
186
187 #define EAL_PARAM_REQ "/eal/params"
188 #define EAL_APP_PARAM_REQ "/eal/app_params"
189
190 /* callback handler for telemetry library to report out EAL flags */
191 int
192 handle_eal_info_request(const char *cmd, const char *params __rte_unused,
193                 struct rte_tel_data *d)
194 {
195         char **args;
196         int used = 0;
197         int i = 0;
198
199         if (strcmp(cmd, EAL_PARAM_REQ) == 0)
200                 args = eal_args;
201         else
202                 args = eal_app_args;
203
204         rte_tel_data_start_array(d, RTE_TEL_STRING_VAL);
205         if (args == NULL || args[0] == NULL)
206                 return 0;
207
208         for ( ; args[i] != NULL; i++)
209                 used = rte_tel_data_add_array_string(d, args[i]);
210         return used;
211 }
212
213 int
214 eal_save_args(int argc, char **argv)
215 {
216         int i, j;
217
218         rte_telemetry_register_cmd(EAL_PARAM_REQ, handle_eal_info_request,
219                         "Returns EAL commandline parameters used. Takes no parameters");
220         rte_telemetry_register_cmd(EAL_APP_PARAM_REQ, handle_eal_info_request,
221                         "Returns app commandline parameters used. Takes no parameters");
222
223         /* clone argv to report out later. We overprovision, but
224          * this does not waste huge amounts of memory
225          */
226         eal_args = calloc(argc + 1, sizeof(*eal_args));
227         if (eal_args == NULL)
228                 return -1;
229
230         for (i = 0; i < argc; i++) {
231                 eal_args[i] = strdup(argv[i]);
232                 if (strcmp(argv[i], "--") == 0)
233                         break;
234         }
235         eal_args[i++] = NULL; /* always finish with NULL */
236
237         /* allow reporting of any app args we know about too */
238         if (i >= argc)
239                 return 0;
240
241         eal_app_args = calloc(argc - i + 1, sizeof(*eal_args));
242         if (eal_app_args == NULL)
243                 return -1;
244
245         for (j = 0; i < argc; j++, i++)
246                 eal_app_args[j] = strdup(argv[i]);
247         eal_app_args[j] = NULL;
248
249         return 0;
250 }
251 #endif
252
253 static int
254 eal_option_device_add(enum rte_devtype type, const char *optarg)
255 {
256         struct device_option *devopt;
257         size_t optlen;
258         int ret;
259
260         optlen = strlen(optarg) + 1;
261         devopt = calloc(1, sizeof(*devopt) + optlen);
262         if (devopt == NULL) {
263                 RTE_LOG(ERR, EAL, "Unable to allocate device option\n");
264                 return -ENOMEM;
265         }
266
267         devopt->type = type;
268         ret = strlcpy(devopt->arg, optarg, optlen);
269         if (ret < 0) {
270                 RTE_LOG(ERR, EAL, "Unable to copy device option\n");
271                 free(devopt);
272                 return -EINVAL;
273         }
274         TAILQ_INSERT_TAIL(&devopt_list, devopt, next);
275         return 0;
276 }
277
278 int
279 eal_option_device_parse(void)
280 {
281         struct device_option *devopt;
282         void *tmp;
283         int ret = 0;
284
285         TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
286                 if (ret == 0) {
287                         ret = rte_devargs_add(devopt->type, devopt->arg);
288                         if (ret)
289                                 RTE_LOG(ERR, EAL, "Unable to parse device '%s'\n",
290                                         devopt->arg);
291                 }
292                 TAILQ_REMOVE(&devopt_list, devopt, next);
293                 free(devopt);
294         }
295         return ret;
296 }
297
298 const char *
299 eal_get_hugefile_prefix(void)
300 {
301         const struct internal_config *internal_conf =
302                 eal_get_internal_configuration();
303
304         if (internal_conf->hugefile_prefix != NULL)
305                 return internal_conf->hugefile_prefix;
306         return HUGEFILE_PREFIX_DEFAULT;
307 }
308
309 void
310 eal_reset_internal_config(struct internal_config *internal_cfg)
311 {
312         int i;
313
314         internal_cfg->memory = 0;
315         internal_cfg->force_nrank = 0;
316         internal_cfg->force_nchannel = 0;
317         internal_cfg->hugefile_prefix = NULL;
318         internal_cfg->hugepage_dir = NULL;
319         internal_cfg->force_sockets = 0;
320         /* zero out the NUMA config */
321         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
322                 internal_cfg->socket_mem[i] = 0;
323         internal_cfg->force_socket_limits = 0;
324         /* zero out the NUMA limits config */
325         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
326                 internal_cfg->socket_limit[i] = 0;
327         /* zero out hugedir descriptors */
328         for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) {
329                 memset(&internal_cfg->hugepage_info[i], 0,
330                                 sizeof(internal_cfg->hugepage_info[0]));
331                 internal_cfg->hugepage_info[i].lock_descriptor = -1;
332         }
333         internal_cfg->base_virtaddr = 0;
334
335 #ifdef LOG_DAEMON
336         internal_cfg->syslog_facility = LOG_DAEMON;
337 #endif
338
339         /* if set to NONE, interrupt mode is determined automatically */
340         internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
341         memset(internal_cfg->vfio_vf_token, 0,
342                         sizeof(internal_cfg->vfio_vf_token));
343
344 #ifdef RTE_LIBEAL_USE_HPET
345         internal_cfg->no_hpet = 0;
346 #else
347         internal_cfg->no_hpet = 1;
348 #endif
349         internal_cfg->vmware_tsc_map = 0;
350         internal_cfg->create_uio_dev = 0;
351         internal_cfg->iova_mode = RTE_IOVA_DC;
352         internal_cfg->user_mbuf_pool_ops_name = NULL;
353         CPU_ZERO(&internal_cfg->ctrl_cpuset);
354         internal_cfg->init_complete = 0;
355         internal_cfg->max_simd_bitwidth.bitwidth = RTE_VECT_DEFAULT_SIMD_BITWIDTH;
356         internal_cfg->max_simd_bitwidth.forced = 0;
357 }
358
359 static int
360 eal_plugin_add(const char *path)
361 {
362         struct shared_driver *solib;
363
364         solib = malloc(sizeof(*solib));
365         if (solib == NULL) {
366                 RTE_LOG(ERR, EAL, "malloc(solib) failed\n");
367                 return -1;
368         }
369         memset(solib, 0, sizeof(*solib));
370         strlcpy(solib->name, path, PATH_MAX);
371         TAILQ_INSERT_TAIL(&solib_list, solib, next);
372
373         return 0;
374 }
375
376 #ifdef RTE_EXEC_ENV_WINDOWS
377 int
378 eal_plugins_init(void)
379 {
380         return 0;
381 }
382 #else
383
384 static int
385 eal_plugindir_init(const char *path)
386 {
387         DIR *d = NULL;
388         struct dirent *dent = NULL;
389         char sopath[PATH_MAX];
390
391         if (path == NULL || *path == '\0')
392                 return 0;
393
394         d = opendir(path);
395         if (d == NULL) {
396                 RTE_LOG(ERR, EAL, "failed to open directory %s: %s\n",
397                         path, strerror(errno));
398                 return -1;
399         }
400
401         while ((dent = readdir(d)) != NULL) {
402                 struct stat sb;
403                 int nlen = strnlen(dent->d_name, sizeof(dent->d_name));
404
405                 /* check if name ends in .so */
406                 if (strcmp(&dent->d_name[nlen - 3], ".so") != 0)
407                         continue;
408
409                 snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name);
410
411                 /* if a regular file, add to list to load */
412                 if (!(stat(sopath, &sb) == 0 && S_ISREG(sb.st_mode)))
413                         continue;
414
415                 if (eal_plugin_add(sopath) == -1)
416                         break;
417         }
418
419         closedir(d);
420         /* XXX this ignores failures from readdir() itself */
421         return (dent == NULL) ? 0 : -1;
422 }
423
424 static int
425 verify_perms(const char *dirpath)
426 {
427         struct stat st;
428
429         /* if not root, check down one level first */
430         if (strcmp(dirpath, "/") != 0) {
431                 static __thread char last_dir_checked[PATH_MAX];
432                 char copy[PATH_MAX];
433                 const char *dir;
434
435                 strlcpy(copy, dirpath, PATH_MAX);
436                 dir = dirname(copy);
437                 if (strncmp(dir, last_dir_checked, PATH_MAX) != 0) {
438                         if (verify_perms(dir) != 0)
439                                 return -1;
440                         strlcpy(last_dir_checked, dir, PATH_MAX);
441                 }
442         }
443
444         /* call stat to check for permissions and ensure not world writable */
445         if (stat(dirpath, &st) != 0) {
446                 RTE_LOG(ERR, EAL, "Error with stat on %s, %s\n",
447                                 dirpath, strerror(errno));
448                 return -1;
449         }
450         if (st.st_mode & S_IWOTH) {
451                 RTE_LOG(ERR, EAL,
452                                 "Error, directory path %s is world-writable and insecure\n",
453                                 dirpath);
454                 return -1;
455         }
456
457         return 0;
458 }
459
460 static void *
461 eal_dlopen(const char *pathname)
462 {
463         void *retval = NULL;
464         char *realp = realpath(pathname, NULL);
465
466         if (realp == NULL && errno == ENOENT) {
467                 /* not a full or relative path, try a load from system dirs */
468                 retval = dlopen(pathname, RTLD_NOW);
469                 if (retval == NULL)
470                         RTE_LOG(ERR, EAL, "%s\n", dlerror());
471                 return retval;
472         }
473         if (realp == NULL) {
474                 RTE_LOG(ERR, EAL, "Error with realpath for %s, %s\n",
475                                 pathname, strerror(errno));
476                 goto out;
477         }
478         if (strnlen(realp, PATH_MAX) == PATH_MAX) {
479                 RTE_LOG(ERR, EAL, "Error, driver path greater than PATH_MAX\n");
480                 goto out;
481         }
482
483         /* do permissions checks */
484         if (verify_perms(realp) != 0)
485                 goto out;
486
487         retval = dlopen(realp, RTLD_NOW);
488         if (retval == NULL)
489                 RTE_LOG(ERR, EAL, "%s\n", dlerror());
490 out:
491         free(realp);
492         return retval;
493 }
494
495 int
496 eal_plugins_init(void)
497 {
498         struct shared_driver *solib = NULL;
499         struct stat sb;
500
501         /* If we are not statically linked, add default driver loading
502          * path if it exists as a directory.
503          * (Using dlopen with NOLOAD flag on EAL, will return NULL if the EAL
504          * shared library is not already loaded i.e. it's statically linked.)
505          */
506         if (dlopen("librte_eal.so."ABI_VERSION, RTLD_LAZY | RTLD_NOLOAD) != NULL &&
507                         *default_solib_dir != '\0' &&
508                         stat(default_solib_dir, &sb) == 0 &&
509                         S_ISDIR(sb.st_mode))
510                 eal_plugin_add(default_solib_dir);
511
512         TAILQ_FOREACH(solib, &solib_list, next) {
513
514                 if (stat(solib->name, &sb) == 0 && S_ISDIR(sb.st_mode)) {
515                         if (eal_plugindir_init(solib->name) == -1) {
516                                 RTE_LOG(ERR, EAL,
517                                         "Cannot init plugin directory %s\n",
518                                         solib->name);
519                                 return -1;
520                         }
521                 } else {
522                         RTE_LOG(DEBUG, EAL, "open shared lib %s\n",
523                                 solib->name);
524                         solib->lib_handle = eal_dlopen(solib->name);
525                         if (solib->lib_handle == NULL)
526                                 return -1;
527                 }
528
529         }
530         return 0;
531 }
532 #endif
533
534 /*
535  * Parse the coremask given as argument (hexadecimal string) and fill
536  * the global configuration (core role and core count) with the parsed
537  * value.
538  */
539 static int xdigit2val(unsigned char c)
540 {
541         int val;
542
543         if (isdigit(c))
544                 val = c - '0';
545         else if (isupper(c))
546                 val = c - 'A' + 10;
547         else
548                 val = c - 'a' + 10;
549         return val;
550 }
551
552 static int
553 eal_parse_service_coremask(const char *coremask)
554 {
555         struct rte_config *cfg = rte_eal_get_configuration();
556         int i, j, idx = 0;
557         unsigned int count = 0;
558         char c;
559         int val;
560         uint32_t taken_lcore_count = 0;
561
562         if (coremask == NULL)
563                 return -1;
564         /* Remove all blank characters ahead and after .
565          * Remove 0x/0X if exists.
566          */
567         while (isblank(*coremask))
568                 coremask++;
569         if (coremask[0] == '0' && ((coremask[1] == 'x')
570                 || (coremask[1] == 'X')))
571                 coremask += 2;
572         i = strlen(coremask);
573         while ((i > 0) && isblank(coremask[i - 1]))
574                 i--;
575
576         if (i == 0)
577                 return -1;
578
579         for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
580                 c = coremask[i];
581                 if (isxdigit(c) == 0) {
582                         /* invalid characters */
583                         return -1;
584                 }
585                 val = xdigit2val(c);
586                 for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE;
587                                 j++, idx++) {
588                         if ((1 << j) & val) {
589                                 /* handle main lcore already parsed */
590                                 uint32_t lcore = idx;
591                                 if (main_lcore_parsed &&
592                                                 cfg->main_lcore == lcore) {
593                                         RTE_LOG(ERR, EAL,
594                                                 "lcore %u is main lcore, cannot use as service core\n",
595                                                 idx);
596                                         return -1;
597                                 }
598
599                                 if (eal_cpu_detected(idx) == 0) {
600                                         RTE_LOG(ERR, EAL,
601                                                 "lcore %u unavailable\n", idx);
602                                         return -1;
603                                 }
604
605                                 if (cfg->lcore_role[idx] == ROLE_RTE)
606                                         taken_lcore_count++;
607
608                                 lcore_config[idx].core_role = ROLE_SERVICE;
609                                 count++;
610                         }
611                 }
612         }
613
614         for (; i >= 0; i--)
615                 if (coremask[i] != '0')
616                         return -1;
617
618         for (; idx < RTE_MAX_LCORE; idx++)
619                 lcore_config[idx].core_index = -1;
620
621         if (count == 0)
622                 return -1;
623
624         if (core_parsed && taken_lcore_count != count) {
625                 RTE_LOG(WARNING, EAL,
626                         "Not all service cores are in the coremask. "
627                         "Please ensure -c or -l includes service cores\n");
628         }
629
630         cfg->service_lcore_count = count;
631         return 0;
632 }
633
634 static int
635 eal_service_cores_parsed(void)
636 {
637         int idx;
638         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
639                 if (lcore_config[idx].core_role == ROLE_SERVICE)
640                         return 1;
641         }
642         return 0;
643 }
644
645 static int
646 update_lcore_config(int *cores)
647 {
648         struct rte_config *cfg = rte_eal_get_configuration();
649         unsigned int count = 0;
650         unsigned int i;
651         int ret = 0;
652
653         for (i = 0; i < RTE_MAX_LCORE; i++) {
654                 if (cores[i] != -1) {
655                         if (eal_cpu_detected(i) == 0) {
656                                 RTE_LOG(ERR, EAL, "lcore %u unavailable\n", i);
657                                 ret = -1;
658                                 continue;
659                         }
660                         cfg->lcore_role[i] = ROLE_RTE;
661                         count++;
662                 } else {
663                         cfg->lcore_role[i] = ROLE_OFF;
664                 }
665                 lcore_config[i].core_index = cores[i];
666         }
667         if (!ret)
668                 cfg->lcore_count = count;
669         return ret;
670 }
671
672 static int
673 eal_parse_coremask(const char *coremask, int *cores)
674 {
675         unsigned count = 0;
676         int i, j, idx;
677         int val;
678         char c;
679
680         for (idx = 0; idx < RTE_MAX_LCORE; idx++)
681                 cores[idx] = -1;
682         idx = 0;
683
684         /* Remove all blank characters ahead and after .
685          * Remove 0x/0X if exists.
686          */
687         while (isblank(*coremask))
688                 coremask++;
689         if (coremask[0] == '0' && ((coremask[1] == 'x')
690                 || (coremask[1] == 'X')))
691                 coremask += 2;
692         i = strlen(coremask);
693         while ((i > 0) && isblank(coremask[i - 1]))
694                 i--;
695         if (i == 0)
696                 return -1;
697
698         for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
699                 c = coremask[i];
700                 if (isxdigit(c) == 0) {
701                         /* invalid characters */
702                         return -1;
703                 }
704                 val = xdigit2val(c);
705                 for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++)
706                 {
707                         if ((1 << j) & val) {
708                                 cores[idx] = count;
709                                 count++;
710                         }
711                 }
712         }
713         for (; i >= 0; i--)
714                 if (coremask[i] != '0')
715                         return -1;
716         if (count == 0)
717                 return -1;
718         return 0;
719 }
720
721 static int
722 eal_parse_service_corelist(const char *corelist)
723 {
724         struct rte_config *cfg = rte_eal_get_configuration();
725         int i, idx = 0;
726         unsigned count = 0;
727         char *end = NULL;
728         int min, max;
729         uint32_t taken_lcore_count = 0;
730
731         if (corelist == NULL)
732                 return -1;
733
734         /* Remove all blank characters ahead and after */
735         while (isblank(*corelist))
736                 corelist++;
737         i = strlen(corelist);
738         while ((i > 0) && isblank(corelist[i - 1]))
739                 i--;
740
741         /* Get list of cores */
742         min = RTE_MAX_LCORE;
743         do {
744                 while (isblank(*corelist))
745                         corelist++;
746                 if (*corelist == '\0')
747                         return -1;
748                 errno = 0;
749                 idx = strtoul(corelist, &end, 10);
750                 if (errno || end == NULL)
751                         return -1;
752                 while (isblank(*end))
753                         end++;
754                 if (*end == '-') {
755                         min = idx;
756                 } else if ((*end == ',') || (*end == '\0')) {
757                         max = idx;
758                         if (min == RTE_MAX_LCORE)
759                                 min = idx;
760                         for (idx = min; idx <= max; idx++) {
761                                 if (cfg->lcore_role[idx] != ROLE_SERVICE) {
762                                         /* handle main lcore already parsed */
763                                         uint32_t lcore = idx;
764                                         if (cfg->main_lcore == lcore &&
765                                                         main_lcore_parsed) {
766                                                 RTE_LOG(ERR, EAL,
767                                                         "Error: lcore %u is main lcore, cannot use as service core\n",
768                                                         idx);
769                                                 return -1;
770                                         }
771                                         if (cfg->lcore_role[idx] == ROLE_RTE)
772                                                 taken_lcore_count++;
773
774                                         lcore_config[idx].core_role =
775                                                         ROLE_SERVICE;
776                                         count++;
777                                 }
778                         }
779                         min = RTE_MAX_LCORE;
780                 } else
781                         return -1;
782                 corelist = end + 1;
783         } while (*end != '\0');
784
785         if (count == 0)
786                 return -1;
787
788         if (core_parsed && taken_lcore_count != count) {
789                 RTE_LOG(WARNING, EAL,
790                         "Not all service cores were in the coremask. "
791                         "Please ensure -c or -l includes service cores\n");
792         }
793
794         return 0;
795 }
796
797 static int
798 eal_parse_corelist(const char *corelist, int *cores)
799 {
800         unsigned count = 0;
801         char *end = NULL;
802         int min, max;
803         int idx;
804
805         for (idx = 0; idx < RTE_MAX_LCORE; idx++)
806                 cores[idx] = -1;
807
808         /* Remove all blank characters ahead */
809         while (isblank(*corelist))
810                 corelist++;
811
812         /* Get list of cores */
813         min = RTE_MAX_LCORE;
814         do {
815                 while (isblank(*corelist))
816                         corelist++;
817                 if (*corelist == '\0')
818                         return -1;
819                 errno = 0;
820                 idx = strtol(corelist, &end, 10);
821                 if (errno || end == NULL)
822                         return -1;
823                 if (idx < 0 || idx >= RTE_MAX_LCORE)
824                         return -1;
825                 while (isblank(*end))
826                         end++;
827                 if (*end == '-') {
828                         min = idx;
829                 } else if ((*end == ',') || (*end == '\0')) {
830                         max = idx;
831                         if (min == RTE_MAX_LCORE)
832                                 min = idx;
833                         for (idx = min; idx <= max; idx++) {
834                                 if (cores[idx] == -1) {
835                                         cores[idx] = count;
836                                         count++;
837                                 }
838                         }
839                         min = RTE_MAX_LCORE;
840                 } else
841                         return -1;
842                 corelist = end + 1;
843         } while (*end != '\0');
844
845         if (count == 0)
846                 return -1;
847         return 0;
848 }
849
850 /* Changes the lcore id of the main thread */
851 static int
852 eal_parse_main_lcore(const char *arg)
853 {
854         char *parsing_end;
855         struct rte_config *cfg = rte_eal_get_configuration();
856
857         errno = 0;
858         cfg->main_lcore = (uint32_t) strtol(arg, &parsing_end, 0);
859         if (errno || parsing_end[0] != 0)
860                 return -1;
861         if (cfg->main_lcore >= RTE_MAX_LCORE)
862                 return -1;
863         main_lcore_parsed = 1;
864
865         /* ensure main core is not used as service core */
866         if (lcore_config[cfg->main_lcore].core_role == ROLE_SERVICE) {
867                 RTE_LOG(ERR, EAL,
868                         "Error: Main lcore is used as a service core\n");
869                 return -1;
870         }
871
872         return 0;
873 }
874
875 /*
876  * Parse elem, the elem could be single number/range or '(' ')' group
877  * 1) A single number elem, it's just a simple digit. e.g. 9
878  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
879  * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
880  *    Within group elem, '-' used for a range separator;
881  *                       ',' used for a single number.
882  */
883 static int
884 eal_parse_set(const char *input, rte_cpuset_t *set)
885 {
886         unsigned idx;
887         const char *str = input;
888         char *end = NULL;
889         unsigned min, max;
890
891         CPU_ZERO(set);
892
893         while (isblank(*str))
894                 str++;
895
896         /* only digit or left bracket is qualify for start point */
897         if ((!isdigit(*str) && *str != '(') || *str == '\0')
898                 return -1;
899
900         /* process single number or single range of number */
901         if (*str != '(') {
902                 errno = 0;
903                 idx = strtoul(str, &end, 10);
904                 if (errno || end == NULL || idx >= CPU_SETSIZE)
905                         return -1;
906                 else {
907                         while (isblank(*end))
908                                 end++;
909
910                         min = idx;
911                         max = idx;
912                         if (*end == '-') {
913                                 /* process single <number>-<number> */
914                                 end++;
915                                 while (isblank(*end))
916                                         end++;
917                                 if (!isdigit(*end))
918                                         return -1;
919
920                                 errno = 0;
921                                 idx = strtoul(end, &end, 10);
922                                 if (errno || end == NULL || idx >= CPU_SETSIZE)
923                                         return -1;
924                                 max = idx;
925                                 while (isblank(*end))
926                                         end++;
927                                 if (*end != ',' && *end != '\0')
928                                         return -1;
929                         }
930
931                         if (*end != ',' && *end != '\0' &&
932                             *end != '@')
933                                 return -1;
934
935                         for (idx = RTE_MIN(min, max);
936                              idx <= RTE_MAX(min, max); idx++)
937                                 CPU_SET(idx, set);
938
939                         return end - input;
940                 }
941         }
942
943         /* process set within bracket */
944         str++;
945         while (isblank(*str))
946                 str++;
947         if (*str == '\0')
948                 return -1;
949
950         min = RTE_MAX_LCORE;
951         do {
952
953                 /* go ahead to the first digit */
954                 while (isblank(*str))
955                         str++;
956                 if (!isdigit(*str))
957                         return -1;
958
959                 /* get the digit value */
960                 errno = 0;
961                 idx = strtoul(str, &end, 10);
962                 if (errno || end == NULL || idx >= CPU_SETSIZE)
963                         return -1;
964
965                 /* go ahead to separator '-',',' and ')' */
966                 while (isblank(*end))
967                         end++;
968                 if (*end == '-') {
969                         if (min == RTE_MAX_LCORE)
970                                 min = idx;
971                         else /* avoid continuous '-' */
972                                 return -1;
973                 } else if ((*end == ',') || (*end == ')')) {
974                         max = idx;
975                         if (min == RTE_MAX_LCORE)
976                                 min = idx;
977                         for (idx = RTE_MIN(min, max);
978                              idx <= RTE_MAX(min, max); idx++)
979                                 CPU_SET(idx, set);
980
981                         min = RTE_MAX_LCORE;
982                 } else
983                         return -1;
984
985                 str = end + 1;
986         } while (*end != '\0' && *end != ')');
987
988         /*
989          * to avoid failure that tail blank makes end character check fail
990          * in eal_parse_lcores( )
991          */
992         while (isblank(*str))
993                 str++;
994
995         return str - input;
996 }
997
998 static int
999 check_cpuset(rte_cpuset_t *set)
1000 {
1001         unsigned int idx;
1002
1003         for (idx = 0; idx < CPU_SETSIZE; idx++) {
1004                 if (!CPU_ISSET(idx, set))
1005                         continue;
1006
1007                 if (eal_cpu_detected(idx) == 0) {
1008                         RTE_LOG(ERR, EAL, "core %u "
1009                                 "unavailable\n", idx);
1010                         return -1;
1011                 }
1012         }
1013         return 0;
1014 }
1015
1016 /*
1017  * The format pattern: --lcores='<lcores[@cpus]>[<,lcores[@cpus]>...]'
1018  * lcores, cpus could be a single digit/range or a group.
1019  * '(' and ')' are necessary if it's a group.
1020  * If not supply '@cpus', the value of cpus uses the same as lcores.
1021  * e.g. '1,2@(5-7),(3-5)@(0,2),(0,6),7-8' means start 9 EAL thread as below
1022  *   lcore 0 runs on cpuset 0x41 (cpu 0,6)
1023  *   lcore 1 runs on cpuset 0x2 (cpu 1)
1024  *   lcore 2 runs on cpuset 0xe0 (cpu 5,6,7)
1025  *   lcore 3,4,5 runs on cpuset 0x5 (cpu 0,2)
1026  *   lcore 6 runs on cpuset 0x41 (cpu 0,6)
1027  *   lcore 7 runs on cpuset 0x80 (cpu 7)
1028  *   lcore 8 runs on cpuset 0x100 (cpu 8)
1029  */
1030 static int
1031 eal_parse_lcores(const char *lcores)
1032 {
1033         struct rte_config *cfg = rte_eal_get_configuration();
1034         rte_cpuset_t lcore_set;
1035         unsigned int set_count;
1036         unsigned idx = 0;
1037         unsigned count = 0;
1038         const char *lcore_start = NULL;
1039         const char *end = NULL;
1040         int offset;
1041         rte_cpuset_t cpuset;
1042         int lflags;
1043         int ret = -1;
1044
1045         if (lcores == NULL)
1046                 return -1;
1047
1048         /* Remove all blank characters ahead and after */
1049         while (isblank(*lcores))
1050                 lcores++;
1051
1052         CPU_ZERO(&cpuset);
1053
1054         /* Reset lcore config */
1055         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
1056                 cfg->lcore_role[idx] = ROLE_OFF;
1057                 lcore_config[idx].core_index = -1;
1058                 CPU_ZERO(&lcore_config[idx].cpuset);
1059         }
1060
1061         /* Get list of cores */
1062         do {
1063                 while (isblank(*lcores))
1064                         lcores++;
1065                 if (*lcores == '\0')
1066                         goto err;
1067
1068                 lflags = 0;
1069
1070                 /* record lcore_set start point */
1071                 lcore_start = lcores;
1072
1073                 /* go across a complete bracket */
1074                 if (*lcore_start == '(') {
1075                         lcores += strcspn(lcores, ")");
1076                         if (*lcores++ == '\0')
1077                                 goto err;
1078                 }
1079
1080                 /* scan the separator '@', ','(next) or '\0'(finish) */
1081                 lcores += strcspn(lcores, "@,");
1082
1083                 if (*lcores == '@') {
1084                         /* explicit assign cpuset and update the end cursor */
1085                         offset = eal_parse_set(lcores + 1, &cpuset);
1086                         if (offset < 0)
1087                                 goto err;
1088                         end = lcores + 1 + offset;
1089                 } else { /* ',' or '\0' */
1090                         /* haven't given cpuset, current loop done */
1091                         end = lcores;
1092
1093                         /* go back to check <number>-<number> */
1094                         offset = strcspn(lcore_start, "(-");
1095                         if (offset < (end - lcore_start) &&
1096                             *(lcore_start + offset) != '(')
1097                                 lflags = 1;
1098                 }
1099
1100                 if (*end != ',' && *end != '\0')
1101                         goto err;
1102
1103                 /* parse lcore_set from start point */
1104                 if (eal_parse_set(lcore_start, &lcore_set) < 0)
1105                         goto err;
1106
1107                 /* without '@', by default using lcore_set as cpuset */
1108                 if (*lcores != '@')
1109                         rte_memcpy(&cpuset, &lcore_set, sizeof(cpuset));
1110
1111                 set_count = CPU_COUNT(&lcore_set);
1112                 /* start to update lcore_set */
1113                 for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
1114                         if (!CPU_ISSET(idx, &lcore_set))
1115                                 continue;
1116                         set_count--;
1117
1118                         if (cfg->lcore_role[idx] != ROLE_RTE) {
1119                                 lcore_config[idx].core_index = count;
1120                                 cfg->lcore_role[idx] = ROLE_RTE;
1121                                 count++;
1122                         }
1123
1124                         if (lflags) {
1125                                 CPU_ZERO(&cpuset);
1126                                 CPU_SET(idx, &cpuset);
1127                         }
1128
1129                         if (check_cpuset(&cpuset) < 0)
1130                                 goto err;
1131                         rte_memcpy(&lcore_config[idx].cpuset, &cpuset,
1132                                    sizeof(rte_cpuset_t));
1133                 }
1134
1135                 /* some cores from the lcore_set can't be handled by EAL */
1136                 if (set_count != 0)
1137                         goto err;
1138
1139                 lcores = end + 1;
1140         } while (*end != '\0');
1141
1142         if (count == 0)
1143                 goto err;
1144
1145         cfg->lcore_count = count;
1146         ret = 0;
1147
1148 err:
1149
1150         return ret;
1151 }
1152
1153 #ifndef RTE_EXEC_ENV_WINDOWS
1154 static int
1155 eal_parse_syslog(const char *facility, struct internal_config *conf)
1156 {
1157         int i;
1158         static const struct {
1159                 const char *name;
1160                 int value;
1161         } map[] = {
1162                 { "auth", LOG_AUTH },
1163                 { "cron", LOG_CRON },
1164                 { "daemon", LOG_DAEMON },
1165                 { "ftp", LOG_FTP },
1166                 { "kern", LOG_KERN },
1167                 { "lpr", LOG_LPR },
1168                 { "mail", LOG_MAIL },
1169                 { "news", LOG_NEWS },
1170                 { "syslog", LOG_SYSLOG },
1171                 { "user", LOG_USER },
1172                 { "uucp", LOG_UUCP },
1173                 { "local0", LOG_LOCAL0 },
1174                 { "local1", LOG_LOCAL1 },
1175                 { "local2", LOG_LOCAL2 },
1176                 { "local3", LOG_LOCAL3 },
1177                 { "local4", LOG_LOCAL4 },
1178                 { "local5", LOG_LOCAL5 },
1179                 { "local6", LOG_LOCAL6 },
1180                 { "local7", LOG_LOCAL7 },
1181                 { NULL, 0 }
1182         };
1183
1184         for (i = 0; map[i].name; i++) {
1185                 if (!strcmp(facility, map[i].name)) {
1186                         conf->syslog_facility = map[i].value;
1187                         return 0;
1188                 }
1189         }
1190         return -1;
1191 }
1192 #endif
1193
1194 static int
1195 eal_parse_log_priority(const char *level)
1196 {
1197         static const char * const levels[] = {
1198                 [RTE_LOG_EMERG]   = "emergency",
1199                 [RTE_LOG_ALERT]   = "alert",
1200                 [RTE_LOG_CRIT]    = "critical",
1201                 [RTE_LOG_ERR]     = "error",
1202                 [RTE_LOG_WARNING] = "warning",
1203                 [RTE_LOG_NOTICE]  = "notice",
1204                 [RTE_LOG_INFO]    = "info",
1205                 [RTE_LOG_DEBUG]   = "debug",
1206         };
1207         size_t len = strlen(level);
1208         unsigned long tmp;
1209         char *end;
1210         unsigned int i;
1211
1212         if (len == 0)
1213                 return -1;
1214
1215         /* look for named values, skip 0 which is not a valid level */
1216         for (i = 1; i < RTE_DIM(levels); i++) {
1217                 if (strncmp(levels[i], level, len) == 0)
1218                         return i;
1219         }
1220
1221         /* not a string, maybe it is numeric */
1222         errno = 0;
1223         tmp = strtoul(level, &end, 0);
1224
1225         /* check for errors */
1226         if (errno != 0 || end == NULL || *end != '\0' ||
1227             tmp >= UINT32_MAX)
1228                 return -1;
1229
1230         return tmp;
1231 }
1232
1233 static int
1234 eal_parse_log_level(const char *arg)
1235 {
1236         const char *pattern = NULL;
1237         const char *regex = NULL;
1238         char *str, *level;
1239         int priority;
1240
1241         str = strdup(arg);
1242         if (str == NULL)
1243                 return -1;
1244
1245         if ((level = strchr(str, ','))) {
1246                 regex = str;
1247                 *level++ = '\0';
1248         } else if ((level = strchr(str, ':'))) {
1249                 pattern = str;
1250                 *level++ = '\0';
1251         } else {
1252                 level = str;
1253         }
1254
1255         priority = eal_parse_log_priority(level);
1256         if (priority < 0) {
1257                 fprintf(stderr, "invalid log priority: %s\n", level);
1258                 goto fail;
1259         }
1260
1261         if (regex) {
1262                 if (rte_log_set_level_regexp(regex, priority) < 0) {
1263                         fprintf(stderr, "cannot set log level %s,%d\n",
1264                                 regex, priority);
1265                         goto fail;
1266                 }
1267                 if (rte_log_save_regexp(regex, priority) < 0)
1268                         goto fail;
1269         } else if (pattern) {
1270                 if (rte_log_set_level_pattern(pattern, priority) < 0) {
1271                         fprintf(stderr, "cannot set log level %s:%d\n",
1272                                 pattern, priority);
1273                         goto fail;
1274                 }
1275                 if (rte_log_save_pattern(pattern, priority) < 0)
1276                         goto fail;
1277         } else {
1278                 rte_log_set_global_level(priority);
1279         }
1280
1281         free(str);
1282         return 0;
1283
1284 fail:
1285         free(str);
1286         return -1;
1287 }
1288
1289 static enum rte_proc_type_t
1290 eal_parse_proc_type(const char *arg)
1291 {
1292         if (strncasecmp(arg, "primary", sizeof("primary")) == 0)
1293                 return RTE_PROC_PRIMARY;
1294         if (strncasecmp(arg, "secondary", sizeof("secondary")) == 0)
1295                 return RTE_PROC_SECONDARY;
1296         if (strncasecmp(arg, "auto", sizeof("auto")) == 0)
1297                 return RTE_PROC_AUTO;
1298
1299         return RTE_PROC_INVALID;
1300 }
1301
1302 static int
1303 eal_parse_iova_mode(const char *name)
1304 {
1305         int mode;
1306         struct internal_config *internal_conf =
1307                 eal_get_internal_configuration();
1308
1309         if (name == NULL)
1310                 return -1;
1311
1312         if (!strcmp("pa", name))
1313                 mode = RTE_IOVA_PA;
1314         else if (!strcmp("va", name))
1315                 mode = RTE_IOVA_VA;
1316         else
1317                 return -1;
1318
1319         internal_conf->iova_mode = mode;
1320         return 0;
1321 }
1322
1323 static int
1324 eal_parse_simd_bitwidth(const char *arg)
1325 {
1326         char *end;
1327         unsigned long bitwidth;
1328         int ret;
1329         struct internal_config *internal_conf =
1330                 eal_get_internal_configuration();
1331
1332         if (arg == NULL || arg[0] == '\0')
1333                 return -1;
1334
1335         errno = 0;
1336         bitwidth = strtoul(arg, &end, 0);
1337
1338         /* check for errors */
1339         if (errno != 0 || end == NULL || *end != '\0' || bitwidth > RTE_VECT_SIMD_MAX)
1340                 return -1;
1341
1342         if (bitwidth == 0)
1343                 bitwidth = (unsigned long) RTE_VECT_SIMD_MAX;
1344         ret = rte_vect_set_max_simd_bitwidth(bitwidth);
1345         if (ret < 0)
1346                 return -1;
1347         internal_conf->max_simd_bitwidth.forced = 1;
1348         return 0;
1349 }
1350
1351 static int
1352 eal_parse_base_virtaddr(const char *arg)
1353 {
1354         char *end;
1355         uint64_t addr;
1356         struct internal_config *internal_conf =
1357                 eal_get_internal_configuration();
1358
1359         errno = 0;
1360         addr = strtoull(arg, &end, 16);
1361
1362         /* check for errors */
1363         if ((errno != 0) || (arg[0] == '\0') || end == NULL || (*end != '\0'))
1364                 return -1;
1365
1366         /* make sure we don't exceed 32-bit boundary on 32-bit target */
1367 #ifndef RTE_ARCH_64
1368         if (addr >= UINTPTR_MAX)
1369                 return -1;
1370 #endif
1371
1372         /* align the addr on 16M boundary, 16MB is the minimum huge page
1373          * size on IBM Power architecture. If the addr is aligned to 16MB,
1374          * it can align to 2MB for x86. So this alignment can also be used
1375          * on x86 and other architectures.
1376          */
1377         internal_conf->base_virtaddr =
1378                 RTE_PTR_ALIGN_CEIL((uintptr_t)addr, (size_t)RTE_PGSIZE_16M);
1379
1380         return 0;
1381 }
1382
1383 /* caller is responsible for freeing the returned string */
1384 static char *
1385 available_cores(void)
1386 {
1387         char *str = NULL;
1388         int previous;
1389         int sequence;
1390         char *tmp;
1391         int idx;
1392
1393         /* find the first available cpu */
1394         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
1395                 if (eal_cpu_detected(idx) == 0)
1396                         continue;
1397                 break;
1398         }
1399         if (idx >= RTE_MAX_LCORE)
1400                 return NULL;
1401
1402         /* first sequence */
1403         if (asprintf(&str, "%d", idx) < 0)
1404                 return NULL;
1405         previous = idx;
1406         sequence = 0;
1407
1408         for (idx++ ; idx < RTE_MAX_LCORE; idx++) {
1409                 if (eal_cpu_detected(idx) == 0)
1410                         continue;
1411
1412                 if (idx == previous + 1) {
1413                         previous = idx;
1414                         sequence = 1;
1415                         continue;
1416                 }
1417
1418                 /* finish current sequence */
1419                 if (sequence) {
1420                         if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
1421                                 free(str);
1422                                 return NULL;
1423                         }
1424                         free(str);
1425                         str = tmp;
1426                 }
1427
1428                 /* new sequence */
1429                 if (asprintf(&tmp, "%s,%d", str, idx) < 0) {
1430                         free(str);
1431                         return NULL;
1432                 }
1433                 free(str);
1434                 str = tmp;
1435                 previous = idx;
1436                 sequence = 0;
1437         }
1438
1439         /* finish last sequence */
1440         if (sequence) {
1441                 if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
1442                         free(str);
1443                         return NULL;
1444                 }
1445                 free(str);
1446                 str = tmp;
1447         }
1448
1449         return str;
1450 }
1451
1452 int
1453 eal_parse_common_option(int opt, const char *optarg,
1454                         struct internal_config *conf)
1455 {
1456         static int b_used;
1457         static int a_used;
1458
1459         switch (opt) {
1460         case OPT_PCI_BLACKLIST_NUM:
1461                 fprintf(stderr,
1462                         "Option --pci-blacklist is deprecated, use -b, --block instead\n");
1463                 /* fallthrough */
1464         case 'b':
1465                 if (a_used)
1466                         goto ba_conflict;
1467                 if (eal_option_device_add(RTE_DEVTYPE_BLOCKED, optarg) < 0)
1468                         return -1;
1469                 b_used = 1;
1470                 break;
1471
1472         case 'w':
1473                 fprintf(stderr,
1474                         "Option -w, --pci-whitelist is deprecated, use -a, --allow option instead\n");
1475                 /* fallthrough */
1476         case 'a':
1477                 if (b_used)
1478                         goto ba_conflict;
1479                 if (eal_option_device_add(RTE_DEVTYPE_ALLOWED, optarg) < 0)
1480                         return -1;
1481                 a_used = 1;
1482                 break;
1483         /* coremask */
1484         case 'c': {
1485                 int lcore_indexes[RTE_MAX_LCORE];
1486
1487                 if (eal_service_cores_parsed())
1488                         RTE_LOG(WARNING, EAL,
1489                                 "Service cores parsed before dataplane cores. Please ensure -c is before -s or -S\n");
1490                 if (eal_parse_coremask(optarg, lcore_indexes) < 0) {
1491                         RTE_LOG(ERR, EAL, "invalid coremask syntax\n");
1492                         return -1;
1493                 }
1494                 if (update_lcore_config(lcore_indexes) < 0) {
1495                         char *available = available_cores();
1496
1497                         RTE_LOG(ERR, EAL,
1498                                 "invalid coremask, please check specified cores are part of %s\n",
1499                                 available);
1500                         free(available);
1501                         return -1;
1502                 }
1503
1504                 if (core_parsed) {
1505                         RTE_LOG(ERR, EAL, "Option -c is ignored, because (%s) is set!\n",
1506                                 (core_parsed == LCORE_OPT_LST) ? "-l" :
1507                                 (core_parsed == LCORE_OPT_MAP) ? "--lcore" :
1508                                 "-c");
1509                         return -1;
1510                 }
1511
1512                 core_parsed = LCORE_OPT_MSK;
1513                 break;
1514         }
1515         /* corelist */
1516         case 'l': {
1517                 int lcore_indexes[RTE_MAX_LCORE];
1518
1519                 if (eal_service_cores_parsed())
1520                         RTE_LOG(WARNING, EAL,
1521                                 "Service cores parsed before dataplane cores. Please ensure -l is before -s or -S\n");
1522
1523                 if (eal_parse_corelist(optarg, lcore_indexes) < 0) {
1524                         RTE_LOG(ERR, EAL, "invalid core list syntax\n");
1525                         return -1;
1526                 }
1527                 if (update_lcore_config(lcore_indexes) < 0) {
1528                         char *available = available_cores();
1529
1530                         RTE_LOG(ERR, EAL,
1531                                 "invalid core list, please check specified cores are part of %s\n",
1532                                 available);
1533                         free(available);
1534                         return -1;
1535                 }
1536
1537                 if (core_parsed) {
1538                         RTE_LOG(ERR, EAL, "Option -l is ignored, because (%s) is set!\n",
1539                                 (core_parsed == LCORE_OPT_MSK) ? "-c" :
1540                                 (core_parsed == LCORE_OPT_MAP) ? "--lcore" :
1541                                 "-l");
1542                         return -1;
1543                 }
1544
1545                 core_parsed = LCORE_OPT_LST;
1546                 break;
1547         }
1548         /* service coremask */
1549         case 's':
1550                 if (eal_parse_service_coremask(optarg) < 0) {
1551                         RTE_LOG(ERR, EAL, "invalid service coremask\n");
1552                         return -1;
1553                 }
1554                 break;
1555         /* service corelist */
1556         case 'S':
1557                 if (eal_parse_service_corelist(optarg) < 0) {
1558                         RTE_LOG(ERR, EAL, "invalid service core list\n");
1559                         return -1;
1560                 }
1561                 break;
1562         /* size of memory */
1563         case 'm':
1564                 conf->memory = atoi(optarg);
1565                 conf->memory *= 1024ULL;
1566                 conf->memory *= 1024ULL;
1567                 mem_parsed = 1;
1568                 break;
1569         /* force number of channels */
1570         case 'n':
1571                 conf->force_nchannel = atoi(optarg);
1572                 if (conf->force_nchannel == 0) {
1573                         RTE_LOG(ERR, EAL, "invalid channel number\n");
1574                         return -1;
1575                 }
1576                 break;
1577         /* force number of ranks */
1578         case 'r':
1579                 conf->force_nrank = atoi(optarg);
1580                 if (conf->force_nrank == 0 ||
1581                     conf->force_nrank > 16) {
1582                         RTE_LOG(ERR, EAL, "invalid rank number\n");
1583                         return -1;
1584                 }
1585                 break;
1586         /* force loading of external driver */
1587         case 'd':
1588                 if (eal_plugin_add(optarg) == -1)
1589                         return -1;
1590                 break;
1591         case 'v':
1592                 /* since message is explicitly requested by user, we
1593                  * write message at highest log level so it can always
1594                  * be seen
1595                  * even if info or warning messages are disabled */
1596                 RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
1597                 break;
1598
1599         /* long options */
1600         case OPT_HUGE_UNLINK_NUM:
1601                 conf->hugepage_unlink = 1;
1602                 break;
1603
1604         case OPT_NO_HUGE_NUM:
1605                 conf->no_hugetlbfs = 1;
1606                 /* no-huge is legacy mem */
1607                 conf->legacy_mem = 1;
1608                 break;
1609
1610         case OPT_NO_PCI_NUM:
1611                 conf->no_pci = 1;
1612                 break;
1613
1614         case OPT_NO_HPET_NUM:
1615                 conf->no_hpet = 1;
1616                 break;
1617
1618         case OPT_VMWARE_TSC_MAP_NUM:
1619                 conf->vmware_tsc_map = 1;
1620                 break;
1621
1622         case OPT_NO_SHCONF_NUM:
1623                 conf->no_shconf = 1;
1624                 break;
1625
1626         case OPT_IN_MEMORY_NUM:
1627                 conf->in_memory = 1;
1628                 /* in-memory is a superset of noshconf and huge-unlink */
1629                 conf->no_shconf = 1;
1630                 conf->hugepage_unlink = 1;
1631                 break;
1632
1633         case OPT_PROC_TYPE_NUM:
1634                 conf->process_type = eal_parse_proc_type(optarg);
1635                 break;
1636
1637         case OPT_MASTER_LCORE_NUM:
1638                 fprintf(stderr,
1639                         "Option --" OPT_MASTER_LCORE
1640                         " is deprecated use " OPT_MAIN_LCORE "\n");
1641                 /* fallthrough */
1642         case OPT_MAIN_LCORE_NUM:
1643                 if (eal_parse_main_lcore(optarg) < 0) {
1644                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1645                                         OPT_MAIN_LCORE "\n");
1646                         return -1;
1647                 }
1648                 break;
1649
1650         case OPT_VDEV_NUM:
1651                 if (eal_option_device_add(RTE_DEVTYPE_VIRTUAL,
1652                                 optarg) < 0) {
1653                         return -1;
1654                 }
1655                 break;
1656
1657 #ifndef RTE_EXEC_ENV_WINDOWS
1658         case OPT_SYSLOG_NUM:
1659                 if (eal_parse_syslog(optarg, conf) < 0) {
1660                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1661                                         OPT_SYSLOG "\n");
1662                         return -1;
1663                 }
1664                 break;
1665 #endif
1666
1667         case OPT_LOG_LEVEL_NUM: {
1668                 if (eal_parse_log_level(optarg) < 0) {
1669                         RTE_LOG(ERR, EAL,
1670                                 "invalid parameters for --"
1671                                 OPT_LOG_LEVEL "\n");
1672                         return -1;
1673                 }
1674                 break;
1675         }
1676
1677 #ifndef RTE_EXEC_ENV_WINDOWS
1678         case OPT_TRACE_NUM: {
1679                 if (eal_trace_args_save(optarg) < 0) {
1680                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1681                                 OPT_TRACE "\n");
1682                         return -1;
1683                 }
1684                 break;
1685         }
1686
1687         case OPT_TRACE_DIR_NUM: {
1688                 if (eal_trace_dir_args_save(optarg) < 0) {
1689                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1690                                 OPT_TRACE_DIR "\n");
1691                         return -1;
1692                 }
1693                 break;
1694         }
1695
1696         case OPT_TRACE_BUF_SIZE_NUM: {
1697                 if (eal_trace_bufsz_args_save(optarg) < 0) {
1698                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1699                                 OPT_TRACE_BUF_SIZE "\n");
1700                         return -1;
1701                 }
1702                 break;
1703         }
1704
1705         case OPT_TRACE_MODE_NUM: {
1706                 if (eal_trace_mode_args_save(optarg) < 0) {
1707                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1708                                 OPT_TRACE_MODE "\n");
1709                         return -1;
1710                 }
1711                 break;
1712         }
1713 #endif /* !RTE_EXEC_ENV_WINDOWS */
1714
1715         case OPT_LCORES_NUM:
1716                 if (eal_parse_lcores(optarg) < 0) {
1717                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1718                                 OPT_LCORES "\n");
1719                         return -1;
1720                 }
1721
1722                 if (core_parsed) {
1723                         RTE_LOG(ERR, EAL, "Option --lcore is ignored, because (%s) is set!\n",
1724                                 (core_parsed == LCORE_OPT_LST) ? "-l" :
1725                                 (core_parsed == LCORE_OPT_MSK) ? "-c" :
1726                                 "--lcore");
1727                         return -1;
1728                 }
1729
1730                 core_parsed = LCORE_OPT_MAP;
1731                 break;
1732         case OPT_LEGACY_MEM_NUM:
1733                 conf->legacy_mem = 1;
1734                 break;
1735         case OPT_SINGLE_FILE_SEGMENTS_NUM:
1736                 conf->single_file_segments = 1;
1737                 break;
1738         case OPT_IOVA_MODE_NUM:
1739                 if (eal_parse_iova_mode(optarg) < 0) {
1740                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1741                                 OPT_IOVA_MODE "\n");
1742                         return -1;
1743                 }
1744                 break;
1745         case OPT_BASE_VIRTADDR_NUM:
1746                 if (eal_parse_base_virtaddr(optarg) < 0) {
1747                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1748                                         OPT_BASE_VIRTADDR "\n");
1749                         return -1;
1750                 }
1751                 break;
1752         case OPT_TELEMETRY_NUM:
1753                 break;
1754         case OPT_NO_TELEMETRY_NUM:
1755                 conf->no_telemetry = 1;
1756                 break;
1757         case OPT_FORCE_MAX_SIMD_BITWIDTH_NUM:
1758                 if (eal_parse_simd_bitwidth(optarg) < 0) {
1759                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1760                                         OPT_FORCE_MAX_SIMD_BITWIDTH "\n");
1761                         return -1;
1762                 }
1763                 break;
1764
1765         /* don't know what to do, leave this to caller */
1766         default:
1767                 return 1;
1768
1769         }
1770
1771         return 0;
1772
1773 ba_conflict:
1774         RTE_LOG(ERR, EAL,
1775                 "Options allow (-a) and block (-b) can't be used at the same time\n");
1776         return -1;
1777 }
1778
1779 static void
1780 eal_auto_detect_cores(struct rte_config *cfg)
1781 {
1782         unsigned int lcore_id;
1783         unsigned int removed = 0;
1784         rte_cpuset_t affinity_set;
1785
1786         if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
1787                                 &affinity_set))
1788                 CPU_ZERO(&affinity_set);
1789
1790         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1791                 if (cfg->lcore_role[lcore_id] == ROLE_RTE &&
1792                     !CPU_ISSET(lcore_id, &affinity_set)) {
1793                         cfg->lcore_role[lcore_id] = ROLE_OFF;
1794                         removed++;
1795                 }
1796         }
1797
1798         cfg->lcore_count -= removed;
1799 }
1800
1801 static void
1802 compute_ctrl_threads_cpuset(struct internal_config *internal_cfg)
1803 {
1804         rte_cpuset_t *cpuset = &internal_cfg->ctrl_cpuset;
1805         rte_cpuset_t default_set;
1806         unsigned int lcore_id;
1807
1808         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1809                 if (rte_lcore_has_role(lcore_id, ROLE_OFF))
1810                         continue;
1811                 RTE_CPU_OR(cpuset, cpuset, &lcore_config[lcore_id].cpuset);
1812         }
1813         RTE_CPU_NOT(cpuset, cpuset);
1814
1815         if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
1816                                 &default_set))
1817                 CPU_ZERO(&default_set);
1818
1819         RTE_CPU_AND(cpuset, cpuset, &default_set);
1820
1821         /* if no remaining cpu, use main lcore cpu affinity */
1822         if (!CPU_COUNT(cpuset)) {
1823                 memcpy(cpuset, &lcore_config[rte_get_main_lcore()].cpuset,
1824                         sizeof(*cpuset));
1825         }
1826 }
1827
1828 int
1829 eal_cleanup_config(struct internal_config *internal_cfg)
1830 {
1831         if (internal_cfg->hugefile_prefix != NULL)
1832                 free(internal_cfg->hugefile_prefix);
1833         if (internal_cfg->hugepage_dir != NULL)
1834                 free(internal_cfg->hugepage_dir);
1835         if (internal_cfg->user_mbuf_pool_ops_name != NULL)
1836                 free(internal_cfg->user_mbuf_pool_ops_name);
1837
1838         return 0;
1839 }
1840
1841 int
1842 eal_adjust_config(struct internal_config *internal_cfg)
1843 {
1844         int i;
1845         struct rte_config *cfg = rte_eal_get_configuration();
1846         struct internal_config *internal_conf =
1847                 eal_get_internal_configuration();
1848
1849         if (!core_parsed)
1850                 eal_auto_detect_cores(cfg);
1851
1852         if (internal_conf->process_type == RTE_PROC_AUTO)
1853                 internal_conf->process_type = eal_proc_type_detect();
1854
1855         /* default main lcore is the first one */
1856         if (!main_lcore_parsed) {
1857                 cfg->main_lcore = rte_get_next_lcore(-1, 0, 0);
1858                 if (cfg->main_lcore >= RTE_MAX_LCORE)
1859                         return -1;
1860                 lcore_config[cfg->main_lcore].core_role = ROLE_RTE;
1861         }
1862
1863         compute_ctrl_threads_cpuset(internal_cfg);
1864
1865         /* if no memory amounts were requested, this will result in 0 and
1866          * will be overridden later, right after eal_hugepage_info_init() */
1867         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
1868                 internal_cfg->memory += internal_cfg->socket_mem[i];
1869
1870         return 0;
1871 }
1872
1873 int
1874 eal_check_common_options(struct internal_config *internal_cfg)
1875 {
1876         struct rte_config *cfg = rte_eal_get_configuration();
1877         const struct internal_config *internal_conf =
1878                 eal_get_internal_configuration();
1879
1880         if (cfg->lcore_role[cfg->main_lcore] != ROLE_RTE) {
1881                 RTE_LOG(ERR, EAL, "Main lcore is not enabled for DPDK\n");
1882                 return -1;
1883         }
1884
1885         if (internal_cfg->process_type == RTE_PROC_INVALID) {
1886                 RTE_LOG(ERR, EAL, "Invalid process type specified\n");
1887                 return -1;
1888         }
1889         if (internal_cfg->hugefile_prefix != NULL &&
1890                         strlen(internal_cfg->hugefile_prefix) < 1) {
1891                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_FILE_PREFIX " option\n");
1892                 return -1;
1893         }
1894         if (internal_cfg->hugepage_dir != NULL &&
1895                         strlen(internal_cfg->hugepage_dir) < 1) {
1896                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_HUGE_DIR" option\n");
1897                 return -1;
1898         }
1899         if (internal_cfg->user_mbuf_pool_ops_name != NULL &&
1900                         strlen(internal_cfg->user_mbuf_pool_ops_name) < 1) {
1901                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_MBUF_POOL_OPS_NAME" option\n");
1902                 return -1;
1903         }
1904         if (index(eal_get_hugefile_prefix(), '%') != NULL) {
1905                 RTE_LOG(ERR, EAL, "Invalid char, '%%', in --"OPT_FILE_PREFIX" "
1906                         "option\n");
1907                 return -1;
1908         }
1909         if (mem_parsed && internal_cfg->force_sockets == 1) {
1910                 RTE_LOG(ERR, EAL, "Options -m and --"OPT_SOCKET_MEM" cannot "
1911                         "be specified at the same time\n");
1912                 return -1;
1913         }
1914         if (internal_cfg->no_hugetlbfs && internal_cfg->force_sockets == 1) {
1915                 RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_MEM" cannot "
1916                         "be specified together with --"OPT_NO_HUGE"\n");
1917                 return -1;
1918         }
1919         if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink &&
1920                         !internal_cfg->in_memory) {
1921                 RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
1922                         "be specified together with --"OPT_NO_HUGE"\n");
1923                 return -1;
1924         }
1925         if (internal_conf->force_socket_limits && internal_conf->legacy_mem) {
1926                 RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_LIMIT
1927                         " is only supported in non-legacy memory mode\n");
1928         }
1929         if (internal_cfg->single_file_segments &&
1930                         internal_cfg->hugepage_unlink &&
1931                         !internal_cfg->in_memory) {
1932                 RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE_SEGMENTS" is "
1933                         "not compatible with --"OPT_HUGE_UNLINK"\n");
1934                 return -1;
1935         }
1936         if (internal_cfg->legacy_mem &&
1937                         internal_cfg->in_memory) {
1938                 RTE_LOG(ERR, EAL, "Option --"OPT_LEGACY_MEM" is not compatible "
1939                                 "with --"OPT_IN_MEMORY"\n");
1940                 return -1;
1941         }
1942         if (internal_cfg->legacy_mem && internal_cfg->match_allocations) {
1943                 RTE_LOG(ERR, EAL, "Option --"OPT_LEGACY_MEM" is not compatible "
1944                                 "with --"OPT_MATCH_ALLOCATIONS"\n");
1945                 return -1;
1946         }
1947         if (internal_cfg->no_hugetlbfs && internal_cfg->match_allocations) {
1948                 RTE_LOG(ERR, EAL, "Option --"OPT_NO_HUGE" is not compatible "
1949                                 "with --"OPT_MATCH_ALLOCATIONS"\n");
1950                 return -1;
1951         }
1952         if (internal_cfg->legacy_mem && internal_cfg->memory == 0) {
1953                 RTE_LOG(NOTICE, EAL, "Static memory layout is selected, "
1954                         "amount of reserved memory can be adjusted with "
1955                         "-m or --"OPT_SOCKET_MEM"\n");
1956         }
1957
1958         return 0;
1959 }
1960
1961 uint16_t
1962 rte_vect_get_max_simd_bitwidth(void)
1963 {
1964         const struct internal_config *internal_conf =
1965                 eal_get_internal_configuration();
1966         return internal_conf->max_simd_bitwidth.bitwidth;
1967 }
1968
1969 int
1970 rte_vect_set_max_simd_bitwidth(uint16_t bitwidth)
1971 {
1972         struct internal_config *internal_conf =
1973                 eal_get_internal_configuration();
1974         if (internal_conf->max_simd_bitwidth.forced) {
1975                 RTE_LOG(NOTICE, EAL, "Cannot set max SIMD bitwidth - user runtime override enabled");
1976                 return -EPERM;
1977         }
1978
1979         if (bitwidth < RTE_VECT_SIMD_DISABLED || !rte_is_power_of_2(bitwidth)) {
1980                 RTE_LOG(ERR, EAL, "Invalid bitwidth value!\n");
1981                 return -EINVAL;
1982         }
1983         internal_conf->max_simd_bitwidth.bitwidth = bitwidth;
1984         return 0;
1985 }
1986
1987 void
1988 eal_common_usage(void)
1989 {
1990         printf("[options]\n\n"
1991                "EAL common options:\n"
1992                "  -c COREMASK         Hexadecimal bitmask of cores to run on\n"
1993                "  -l CORELIST         List of cores to run on\n"
1994                "                      The argument format is <c1>[-c2][,c3[-c4],...]\n"
1995                "                      where c1, c2, etc are core indexes between 0 and %d\n"
1996                "  --"OPT_LCORES" COREMAP    Map lcore set to physical cpu set\n"
1997                "                      The argument format is\n"
1998                "                            '<lcores[@cpus]>[<,lcores[@cpus]>...]'\n"
1999                "                      lcores and cpus list are grouped by '(' and ')'\n"
2000                "                      Within the group, '-' is used for range separator,\n"
2001                "                      ',' is used for single number separator.\n"
2002                "                      '( )' can be omitted for single element group,\n"
2003                "                      '@' can be omitted if cpus and lcores have the same value\n"
2004                "  -s SERVICE COREMASK Hexadecimal bitmask of cores to be used as service cores\n"
2005                "  --"OPT_MAIN_LCORE" ID     Core ID that is used as main\n"
2006                "  --"OPT_MBUF_POOL_OPS_NAME" Pool ops name for mbuf to use\n"
2007                "  -n CHANNELS         Number of memory channels\n"
2008                "  -m MB               Memory to allocate (see also --"OPT_SOCKET_MEM")\n"
2009                "  -r RANKS            Force number of memory ranks (don't detect)\n"
2010                "  -b, --block         Add a device to the blocked list.\n"
2011                "                      Prevent EAL from using this device. The argument\n"
2012                "                      format for PCI devices is <domain:bus:devid.func>.\n"
2013                "  -a, --allow         Add a device to the allow list.\n"
2014                "                      Only use the specified devices. The argument format\n"
2015                "                      for PCI devices is <[domain:]bus:devid.func>.\n"
2016                "                      This option can be present several times.\n"
2017                "                      [NOTE: " OPT_DEV_ALLOW " cannot be used with "OPT_DEV_BLOCK" option]\n"
2018                "  --"OPT_VDEV"              Add a virtual device.\n"
2019                "                      The argument format is <driver><id>[,key=val,...]\n"
2020                "                      (ex: --vdev=net_pcap0,iface=eth2).\n"
2021                "  --"OPT_IOVA_MODE"   Set IOVA mode. 'pa' for IOVA_PA\n"
2022                "                      'va' for IOVA_VA\n"
2023                "  -d LIB.so|DIR       Add a driver or driver directory\n"
2024                "                      (can be used multiple times)\n"
2025                "  --"OPT_VMWARE_TSC_MAP"    Use VMware TSC map instead of native RDTSC\n"
2026                "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
2027 #ifndef RTE_EXEC_ENV_WINDOWS
2028                "  --"OPT_SYSLOG"            Set syslog facility\n"
2029 #endif
2030                "  --"OPT_LOG_LEVEL"=<int>   Set global log level\n"
2031                "  --"OPT_LOG_LEVEL"=<type-match>:<int>\n"
2032                "                      Set specific log level\n"
2033 #ifndef RTE_EXEC_ENV_WINDOWS
2034                "  --"OPT_TRACE"=<regex-match>\n"
2035                "                      Enable trace based on regular expression trace name.\n"
2036                "                      By default, the trace is disabled.\n"
2037                "                      User must specify this option to enable trace.\n"
2038                "  --"OPT_TRACE_DIR"=<directory path>\n"
2039                "                      Specify trace directory for trace output.\n"
2040                "                      By default, trace output will created at\n"
2041                "                      $HOME directory and parameter must be\n"
2042                "                      specified once only.\n"
2043                "  --"OPT_TRACE_BUF_SIZE"=<int>\n"
2044                "                      Specify maximum size of allocated memory\n"
2045                "                      for trace output for each thread. Valid\n"
2046                "                      unit can be either 'B|K|M' for 'Bytes',\n"
2047                "                      'KBytes' and 'MBytes' respectively.\n"
2048                "                      Default is 1MB and parameter must be\n"
2049                "                      specified once only.\n"
2050                "  --"OPT_TRACE_MODE"=<o[verwrite] | d[iscard]>\n"
2051                "                      Specify the mode of update of trace\n"
2052                "                      output file. Either update on a file can\n"
2053                "                      be wrapped or discarded when file size\n"
2054                "                      reaches its maximum limit.\n"
2055                "                      Default mode is 'overwrite' and parameter\n"
2056                "                      must be specified once only.\n"
2057 #endif /* !RTE_EXEC_ENV_WINDOWS */
2058                "  -v                  Display version information on startup\n"
2059                "  -h, --help          This help\n"
2060                "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
2061                "                      disable secondary process support\n"
2062                "  --"OPT_BASE_VIRTADDR"     Base virtual address\n"
2063                "  --"OPT_TELEMETRY"   Enable telemetry support (on by default)\n"
2064                "  --"OPT_NO_TELEMETRY"   Disable telemetry support\n"
2065                "  --"OPT_FORCE_MAX_SIMD_BITWIDTH" Force the max SIMD bitwidth\n"
2066                "\nEAL options for DEBUG use only:\n"
2067                "  --"OPT_HUGE_UNLINK"       Unlink hugepage files after init\n"
2068                "  --"OPT_NO_HUGE"           Use malloc instead of hugetlbfs\n"
2069                "  --"OPT_NO_PCI"            Disable PCI\n"
2070                "  --"OPT_NO_HPET"           Disable HPET\n"
2071                "  --"OPT_NO_SHCONF"         No shared config (mmap'd files)\n"
2072                "\n", RTE_MAX_LCORE);
2073 }