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