eal: default to using all cores
[dpdk.git] / lib / librte_eal / common / eal_common_options.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   Copyright(c) 2014 6WIND S.A.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <syslog.h>
38 #include <ctype.h>
39 #include <limits.h>
40 #include <errno.h>
41 #include <getopt.h>
42
43 #include <rte_eal.h>
44 #include <rte_log.h>
45 #include <rte_lcore.h>
46 #include <rte_version.h>
47 #include <rte_devargs.h>
48 #include <rte_memcpy.h>
49
50 #include "eal_internal_cfg.h"
51 #include "eal_options.h"
52 #include "eal_filesystem.h"
53
54 #define BITS_PER_HEX 4
55
56 const char
57 eal_short_options[] =
58         "b:" /* pci-blacklist */
59         "c:" /* coremask */
60         "d:" /* driver */
61         "h"  /* help */
62         "l:" /* corelist */
63         "m:" /* memory size */
64         "n:" /* memory channels */
65         "r:" /* memory ranks */
66         "v"  /* version */
67         "w:" /* pci-whitelist */
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_LCORES,            1, NULL, OPT_LCORES_NUM           },
78         {OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
79         {OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
80         {OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
81         {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
82         {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
83         {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
84         {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
85         {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
86         {OPT_PROC_TYPE,         1, NULL, OPT_PROC_TYPE_NUM        },
87         {OPT_SOCKET_MEM,        1, NULL, OPT_SOCKET_MEM_NUM       },
88         {OPT_SYSLOG,            1, NULL, OPT_SYSLOG_NUM           },
89         {OPT_VDEV,              1, NULL, OPT_VDEV_NUM             },
90         {OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
91         {OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
92         {OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
93         {0,                     0, NULL, 0                        }
94 };
95
96 static int master_lcore_parsed;
97 static int mem_parsed;
98
99 void
100 eal_reset_internal_config(struct internal_config *internal_cfg)
101 {
102         int i;
103
104         internal_cfg->memory = 0;
105         internal_cfg->force_nrank = 0;
106         internal_cfg->force_nchannel = 0;
107         internal_cfg->hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
108         internal_cfg->hugepage_dir = NULL;
109         internal_cfg->force_sockets = 0;
110         /* zero out the NUMA config */
111         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
112                 internal_cfg->socket_mem[i] = 0;
113         /* zero out hugedir descriptors */
114         for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
115                 internal_cfg->hugepage_info[i].lock_descriptor = -1;
116         internal_cfg->base_virtaddr = 0;
117
118         internal_cfg->syslog_facility = LOG_DAEMON;
119         /* default value from build option */
120         internal_cfg->log_level = RTE_LOG_LEVEL;
121
122         internal_cfg->xen_dom0_support = 0;
123
124         /* if set to NONE, interrupt mode is determined automatically */
125         internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
126
127 #ifdef RTE_LIBEAL_USE_HPET
128         internal_cfg->no_hpet = 0;
129 #else
130         internal_cfg->no_hpet = 1;
131 #endif
132         internal_cfg->vmware_tsc_map = 0;
133         internal_cfg->create_uio_dev = 0;
134 }
135
136 /*
137  * Parse the coremask given as argument (hexadecimal string) and fill
138  * the global configuration (core role and core count) with the parsed
139  * value.
140  */
141 static int xdigit2val(unsigned char c)
142 {
143         int val;
144
145         if (isdigit(c))
146                 val = c - '0';
147         else if (isupper(c))
148                 val = c - 'A' + 10;
149         else
150                 val = c - 'a' + 10;
151         return val;
152 }
153
154 static int
155 eal_parse_coremask(const char *coremask)
156 {
157         struct rte_config *cfg = rte_eal_get_configuration();
158         int i, j, idx = 0;
159         unsigned count = 0;
160         char c;
161         int val;
162
163         if (coremask == NULL)
164                 return -1;
165         /* Remove all blank characters ahead and after .
166          * Remove 0x/0X if exists.
167          */
168         while (isblank(*coremask))
169                 coremask++;
170         if (coremask[0] == '0' && ((coremask[1] == 'x')
171                 || (coremask[1] == 'X')))
172                 coremask += 2;
173         i = strlen(coremask);
174         while ((i > 0) && isblank(coremask[i - 1]))
175                 i--;
176         if (i == 0)
177                 return -1;
178
179         for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
180                 c = coremask[i];
181                 if (isxdigit(c) == 0) {
182                         /* invalid characters */
183                         return -1;
184                 }
185                 val = xdigit2val(c);
186                 for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++)
187                 {
188                         if ((1 << j) & val) {
189                                 if (!lcore_config[idx].detected) {
190                                         RTE_LOG(ERR, EAL, "lcore %u "
191                                                 "unavailable\n", idx);
192                                         return -1;
193                                 }
194                                 cfg->lcore_role[idx] = ROLE_RTE;
195                                 lcore_config[idx].core_index = count;
196                                 count++;
197                         } else {
198                                 cfg->lcore_role[idx] = ROLE_OFF;
199                                 lcore_config[idx].core_index = -1;
200                         }
201                 }
202         }
203         for (; i >= 0; i--)
204                 if (coremask[i] != '0')
205                         return -1;
206         for (; idx < RTE_MAX_LCORE; idx++) {
207                 cfg->lcore_role[idx] = ROLE_OFF;
208                 lcore_config[idx].core_index = -1;
209         }
210         if (count == 0)
211                 return -1;
212         /* Update the count of enabled logical cores of the EAL configuration */
213         cfg->lcore_count = count;
214         return 0;
215 }
216
217 static int
218 eal_parse_corelist(const char *corelist)
219 {
220         struct rte_config *cfg = rte_eal_get_configuration();
221         int i, idx = 0;
222         unsigned count = 0;
223         char *end = NULL;
224         int min, max;
225
226         if (corelist == NULL)
227                 return -1;
228
229         /* Remove all blank characters ahead and after */
230         while (isblank(*corelist))
231                 corelist++;
232         i = strlen(corelist);
233         while ((i > 0) && isblank(corelist[i - 1]))
234                 i--;
235
236         /* Reset config */
237         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
238                 cfg->lcore_role[idx] = ROLE_OFF;
239                 lcore_config[idx].core_index = -1;
240         }
241
242         /* Get list of cores */
243         min = RTE_MAX_LCORE;
244         do {
245                 while (isblank(*corelist))
246                         corelist++;
247                 if (*corelist == '\0')
248                         return -1;
249                 errno = 0;
250                 idx = strtoul(corelist, &end, 10);
251                 if (errno || end == NULL)
252                         return -1;
253                 while (isblank(*end))
254                         end++;
255                 if (*end == '-') {
256                         min = idx;
257                 } else if ((*end == ',') || (*end == '\0')) {
258                         max = idx;
259                         if (min == RTE_MAX_LCORE)
260                                 min = idx;
261                         for (idx = min; idx <= max; idx++) {
262                                 if (cfg->lcore_role[idx] != ROLE_RTE) {
263                                         cfg->lcore_role[idx] = ROLE_RTE;
264                                         lcore_config[idx].core_index = count;
265                                         count++;
266                                 }
267                         }
268                         min = RTE_MAX_LCORE;
269                 } else
270                         return -1;
271                 corelist = end + 1;
272         } while (*end != '\0');
273
274         if (count == 0)
275                 return -1;
276
277         /* Update the count of enabled logical cores of the EAL configuration */
278         cfg->lcore_count = count;
279
280         return 0;
281 }
282
283 /* Changes the lcore id of the master thread */
284 static int
285 eal_parse_master_lcore(const char *arg)
286 {
287         char *parsing_end;
288         struct rte_config *cfg = rte_eal_get_configuration();
289
290         errno = 0;
291         cfg->master_lcore = (uint32_t) strtol(arg, &parsing_end, 0);
292         if (errno || parsing_end[0] != 0)
293                 return -1;
294         if (cfg->master_lcore >= RTE_MAX_LCORE)
295                 return -1;
296         master_lcore_parsed = 1;
297         return 0;
298 }
299
300 /*
301  * Parse elem, the elem could be single number/range or '(' ')' group
302  * 1) A single number elem, it's just a simple digit. e.g. 9
303  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
304  * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
305  *    Within group elem, '-' used for a range separator;
306  *                       ',' used for a single number.
307  */
308 static int
309 eal_parse_set(const char *input, uint16_t set[], unsigned num)
310 {
311         unsigned idx;
312         const char *str = input;
313         char *end = NULL;
314         unsigned min, max;
315
316         memset(set, 0, num * sizeof(uint16_t));
317
318         while (isblank(*str))
319                 str++;
320
321         /* only digit or left bracket is qualify for start point */
322         if ((!isdigit(*str) && *str != '(') || *str == '\0')
323                 return -1;
324
325         /* process single number or single range of number */
326         if (*str != '(') {
327                 errno = 0;
328                 idx = strtoul(str, &end, 10);
329                 if (errno || end == NULL || idx >= num)
330                         return -1;
331                 else {
332                         while (isblank(*end))
333                                 end++;
334
335                         min = idx;
336                         max = idx;
337                         if (*end == '-') {
338                                 /* process single <number>-<number> */
339                                 end++;
340                                 while (isblank(*end))
341                                         end++;
342                                 if (!isdigit(*end))
343                                         return -1;
344
345                                 errno = 0;
346                                 idx = strtoul(end, &end, 10);
347                                 if (errno || end == NULL || idx >= num)
348                                         return -1;
349                                 max = idx;
350                                 while (isblank(*end))
351                                         end++;
352                                 if (*end != ',' && *end != '\0')
353                                         return -1;
354                         }
355
356                         if (*end != ',' && *end != '\0' &&
357                             *end != '@')
358                                 return -1;
359
360                         for (idx = RTE_MIN(min, max);
361                              idx <= RTE_MAX(min, max); idx++)
362                                 set[idx] = 1;
363
364                         return end - input;
365                 }
366         }
367
368         /* process set within bracket */
369         str++;
370         while (isblank(*str))
371                 str++;
372         if (*str == '\0')
373                 return -1;
374
375         min = RTE_MAX_LCORE;
376         do {
377
378                 /* go ahead to the first digit */
379                 while (isblank(*str))
380                         str++;
381                 if (!isdigit(*str))
382                         return -1;
383
384                 /* get the digit value */
385                 errno = 0;
386                 idx = strtoul(str, &end, 10);
387                 if (errno || end == NULL || idx >= num)
388                         return -1;
389
390                 /* go ahead to separator '-',',' and ')' */
391                 while (isblank(*end))
392                         end++;
393                 if (*end == '-') {
394                         if (min == RTE_MAX_LCORE)
395                                 min = idx;
396                         else /* avoid continuous '-' */
397                                 return -1;
398                 } else if ((*end == ',') || (*end == ')')) {
399                         max = idx;
400                         if (min == RTE_MAX_LCORE)
401                                 min = idx;
402                         for (idx = RTE_MIN(min, max);
403                              idx <= RTE_MAX(min, max); idx++)
404                                 set[idx] = 1;
405
406                         min = RTE_MAX_LCORE;
407                 } else
408                         return -1;
409
410                 str = end + 1;
411         } while (*end != '\0' && *end != ')');
412
413         return str - input;
414 }
415
416 /* convert from set array to cpuset bitmap */
417 static int
418 convert_to_cpuset(rte_cpuset_t *cpusetp,
419               uint16_t *set, unsigned num)
420 {
421         unsigned idx;
422
423         CPU_ZERO(cpusetp);
424
425         for (idx = 0; idx < num; idx++) {
426                 if (!set[idx])
427                         continue;
428
429                 if (!lcore_config[idx].detected) {
430                         RTE_LOG(ERR, EAL, "core %u "
431                                 "unavailable\n", idx);
432                         return -1;
433                 }
434
435                 CPU_SET(idx, cpusetp);
436         }
437
438         return 0;
439 }
440
441 /*
442  * The format pattern: --lcores='<lcores[@cpus]>[<,lcores[@cpus]>...]'
443  * lcores, cpus could be a single digit/range or a group.
444  * '(' and ')' are necessary if it's a group.
445  * If not supply '@cpus', the value of cpus uses the same as lcores.
446  * e.g. '1,2@(5-7),(3-5)@(0,2),(0,6),7-8' means start 9 EAL thread as below
447  *   lcore 0 runs on cpuset 0x41 (cpu 0,6)
448  *   lcore 1 runs on cpuset 0x2 (cpu 1)
449  *   lcore 2 runs on cpuset 0xe0 (cpu 5,6,7)
450  *   lcore 3,4,5 runs on cpuset 0x5 (cpu 0,2)
451  *   lcore 6 runs on cpuset 0x41 (cpu 0,6)
452  *   lcore 7 runs on cpuset 0x80 (cpu 7)
453  *   lcore 8 runs on cpuset 0x100 (cpu 8)
454  */
455 static int
456 eal_parse_lcores(const char *lcores)
457 {
458         struct rte_config *cfg = rte_eal_get_configuration();
459         static uint16_t set[RTE_MAX_LCORE];
460         unsigned idx = 0;
461         int i;
462         unsigned count = 0;
463         const char *lcore_start = NULL;
464         const char *end = NULL;
465         int offset;
466         rte_cpuset_t cpuset;
467         int lflags = 0;
468         int ret = -1;
469
470         if (lcores == NULL)
471                 return -1;
472
473         /* Remove all blank characters ahead and after */
474         while (isblank(*lcores))
475                 lcores++;
476         i = strlen(lcores);
477         while ((i > 0) && isblank(lcores[i - 1]))
478                 i--;
479
480         CPU_ZERO(&cpuset);
481
482         /* Reset lcore config */
483         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
484                 cfg->lcore_role[idx] = ROLE_OFF;
485                 lcore_config[idx].core_index = -1;
486                 CPU_ZERO(&lcore_config[idx].cpuset);
487         }
488
489         /* Get list of cores */
490         do {
491                 while (isblank(*lcores))
492                         lcores++;
493                 if (*lcores == '\0')
494                         goto err;
495
496                 /* record lcore_set start point */
497                 lcore_start = lcores;
498
499                 /* go across a complete bracket */
500                 if (*lcore_start == '(') {
501                         lcores += strcspn(lcores, ")");
502                         if (*lcores++ == '\0')
503                                 goto err;
504                 }
505
506                 /* scan the separator '@', ','(next) or '\0'(finish) */
507                 lcores += strcspn(lcores, "@,");
508
509                 if (*lcores == '@') {
510                         /* explicit assign cpu_set */
511                         offset = eal_parse_set(lcores + 1, set, RTE_DIM(set));
512                         if (offset < 0)
513                                 goto err;
514
515                         /* prepare cpu_set and update the end cursor */
516                         if (0 > convert_to_cpuset(&cpuset,
517                                                   set, RTE_DIM(set)))
518                                 goto err;
519                         end = lcores + 1 + offset;
520                 } else { /* ',' or '\0' */
521                         /* haven't given cpu_set, current loop done */
522                         end = lcores;
523
524                         /* go back to check <number>-<number> */
525                         offset = strcspn(lcore_start, "(-");
526                         if (offset < (end - lcore_start) &&
527                             *(lcore_start + offset) != '(')
528                                 lflags = 1;
529                 }
530
531                 if (*end != ',' && *end != '\0')
532                         goto err;
533
534                 /* parse lcore_set from start point */
535                 if (0 > eal_parse_set(lcore_start, set, RTE_DIM(set)))
536                         goto err;
537
538                 /* without '@', by default using lcore_set as cpu_set */
539                 if (*lcores != '@' &&
540                     0 > convert_to_cpuset(&cpuset, set, RTE_DIM(set)))
541                         goto err;
542
543                 /* start to update lcore_set */
544                 for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
545                         if (!set[idx])
546                                 continue;
547
548                         if (cfg->lcore_role[idx] != ROLE_RTE) {
549                                 lcore_config[idx].core_index = count;
550                                 cfg->lcore_role[idx] = ROLE_RTE;
551                                 count++;
552                         }
553
554                         if (lflags) {
555                                 CPU_ZERO(&cpuset);
556                                 CPU_SET(idx, &cpuset);
557                         }
558                         rte_memcpy(&lcore_config[idx].cpuset, &cpuset,
559                                    sizeof(rte_cpuset_t));
560                 }
561
562                 lcores = end + 1;
563         } while (*end != '\0');
564
565         if (count == 0)
566                 goto err;
567
568         cfg->lcore_count = count;
569         ret = 0;
570
571 err:
572
573         return ret;
574 }
575
576 static int
577 eal_parse_syslog(const char *facility, struct internal_config *conf)
578 {
579         int i;
580         static struct {
581                 const char *name;
582                 int value;
583         } map[] = {
584                 { "auth", LOG_AUTH },
585                 { "cron", LOG_CRON },
586                 { "daemon", LOG_DAEMON },
587                 { "ftp", LOG_FTP },
588                 { "kern", LOG_KERN },
589                 { "lpr", LOG_LPR },
590                 { "mail", LOG_MAIL },
591                 { "news", LOG_NEWS },
592                 { "syslog", LOG_SYSLOG },
593                 { "user", LOG_USER },
594                 { "uucp", LOG_UUCP },
595                 { "local0", LOG_LOCAL0 },
596                 { "local1", LOG_LOCAL1 },
597                 { "local2", LOG_LOCAL2 },
598                 { "local3", LOG_LOCAL3 },
599                 { "local4", LOG_LOCAL4 },
600                 { "local5", LOG_LOCAL5 },
601                 { "local6", LOG_LOCAL6 },
602                 { "local7", LOG_LOCAL7 },
603                 { NULL, 0 }
604         };
605
606         for (i = 0; map[i].name; i++) {
607                 if (!strcmp(facility, map[i].name)) {
608                         conf->syslog_facility = map[i].value;
609                         return 0;
610                 }
611         }
612         return -1;
613 }
614
615 static int
616 eal_parse_log_level(const char *level, uint32_t *log_level)
617 {
618         char *end;
619         unsigned long tmp;
620
621         errno = 0;
622         tmp = strtoul(level, &end, 0);
623
624         /* check for errors */
625         if ((errno != 0) || (level[0] == '\0') ||
626             end == NULL || (*end != '\0'))
627                 return -1;
628
629         /* log_level is a uint32_t */
630         if (tmp >= UINT32_MAX)
631                 return -1;
632
633         *log_level = tmp;
634         return 0;
635 }
636
637 static enum rte_proc_type_t
638 eal_parse_proc_type(const char *arg)
639 {
640         if (strncasecmp(arg, "primary", sizeof("primary")) == 0)
641                 return RTE_PROC_PRIMARY;
642         if (strncasecmp(arg, "secondary", sizeof("secondary")) == 0)
643                 return RTE_PROC_SECONDARY;
644         if (strncasecmp(arg, "auto", sizeof("auto")) == 0)
645                 return RTE_PROC_AUTO;
646
647         return RTE_PROC_INVALID;
648 }
649
650 int
651 eal_parse_common_option(int opt, const char *optarg,
652                         struct internal_config *conf)
653 {
654         switch (opt) {
655         /* blacklist */
656         case 'b':
657                 if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
658                                 optarg) < 0) {
659                         return -1;
660                 }
661                 break;
662         /* whitelist */
663         case 'w':
664                 if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
665                                 optarg) < 0) {
666                         return -1;
667                 }
668                 break;
669         /* coremask */
670         case 'c':
671                 if (eal_parse_coremask(optarg) < 0) {
672                         RTE_LOG(ERR, EAL, "invalid coremask\n");
673                         return -1;
674                 }
675                 break;
676         /* corelist */
677         case 'l':
678                 if (eal_parse_corelist(optarg) < 0) {
679                         RTE_LOG(ERR, EAL, "invalid core list\n");
680                         return -1;
681                 }
682                 break;
683         /* size of memory */
684         case 'm':
685                 conf->memory = atoi(optarg);
686                 conf->memory *= 1024ULL;
687                 conf->memory *= 1024ULL;
688                 mem_parsed = 1;
689                 break;
690         /* force number of channels */
691         case 'n':
692                 conf->force_nchannel = atoi(optarg);
693                 if (conf->force_nchannel == 0 ||
694                     conf->force_nchannel > 4) {
695                         RTE_LOG(ERR, EAL, "invalid channel number\n");
696                         return -1;
697                 }
698                 break;
699         /* force number of ranks */
700         case 'r':
701                 conf->force_nrank = atoi(optarg);
702                 if (conf->force_nrank == 0 ||
703                     conf->force_nrank > 16) {
704                         RTE_LOG(ERR, EAL, "invalid rank number\n");
705                         return -1;
706                 }
707                 break;
708         case 'v':
709                 /* since message is explicitly requested by user, we
710                  * write message at highest log level so it can always
711                  * be seen
712                  * even if info or warning messages are disabled */
713                 RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
714                 break;
715
716         /* long options */
717         case OPT_NO_HUGE_NUM:
718                 conf->no_hugetlbfs = 1;
719                 break;
720
721         case OPT_NO_PCI_NUM:
722                 conf->no_pci = 1;
723                 break;
724
725         case OPT_NO_HPET_NUM:
726                 conf->no_hpet = 1;
727                 break;
728
729         case OPT_VMWARE_TSC_MAP_NUM:
730                 conf->vmware_tsc_map = 1;
731                 break;
732
733         case OPT_NO_SHCONF_NUM:
734                 conf->no_shconf = 1;
735                 break;
736
737         case OPT_PROC_TYPE_NUM:
738                 conf->process_type = eal_parse_proc_type(optarg);
739                 break;
740
741         case OPT_MASTER_LCORE_NUM:
742                 if (eal_parse_master_lcore(optarg) < 0) {
743                         RTE_LOG(ERR, EAL, "invalid parameter for --"
744                                         OPT_MASTER_LCORE "\n");
745                         return -1;
746                 }
747                 break;
748
749         case OPT_VDEV_NUM:
750                 if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
751                                 optarg) < 0) {
752                         return -1;
753                 }
754                 break;
755
756         case OPT_SYSLOG_NUM:
757                 if (eal_parse_syslog(optarg, conf) < 0) {
758                         RTE_LOG(ERR, EAL, "invalid parameters for --"
759                                         OPT_SYSLOG "\n");
760                         return -1;
761                 }
762                 break;
763
764         case OPT_LOG_LEVEL_NUM: {
765                 uint32_t log;
766
767                 if (eal_parse_log_level(optarg, &log) < 0) {
768                         RTE_LOG(ERR, EAL,
769                                 "invalid parameters for --"
770                                 OPT_LOG_LEVEL "\n");
771                         return -1;
772                 }
773                 conf->log_level = log;
774                 break;
775         }
776         case OPT_LCORES_NUM:
777                 if (eal_parse_lcores(optarg) < 0) {
778                         RTE_LOG(ERR, EAL, "invalid parameter for --"
779                                 OPT_LCORES "\n");
780                         return -1;
781                 }
782                 break;
783
784         /* don't know what to do, leave this to caller */
785         default:
786                 return 1;
787
788         }
789
790         return 0;
791 }
792
793 int
794 eal_adjust_config(struct internal_config *internal_cfg)
795 {
796         int i;
797         struct rte_config *cfg = rte_eal_get_configuration();
798
799         if (internal_config.process_type == RTE_PROC_AUTO)
800                 internal_config.process_type = eal_proc_type_detect();
801
802         /* default master lcore is the first one */
803         if (!master_lcore_parsed)
804                 cfg->master_lcore = rte_get_next_lcore(-1, 0, 0);
805
806         /* if no memory amounts were requested, this will result in 0 and
807          * will be overridden later, right after eal_hugepage_info_init() */
808         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
809                 internal_cfg->memory += internal_cfg->socket_mem[i];
810
811         return 0;
812 }
813
814 int
815 eal_check_common_options(struct internal_config *internal_cfg)
816 {
817         struct rte_config *cfg = rte_eal_get_configuration();
818
819         if (cfg->lcore_role[cfg->master_lcore] != ROLE_RTE) {
820                 RTE_LOG(ERR, EAL, "Master lcore is not enabled for DPDK\n");
821                 return -1;
822         }
823
824         if (internal_cfg->process_type == RTE_PROC_INVALID) {
825                 RTE_LOG(ERR, EAL, "Invalid process type specified\n");
826                 return -1;
827         }
828         if (index(internal_cfg->hugefile_prefix, '%') != NULL) {
829                 RTE_LOG(ERR, EAL, "Invalid char, '%%', in --"OPT_FILE_PREFIX" "
830                         "option\n");
831                 return -1;
832         }
833         if (mem_parsed && internal_cfg->force_sockets == 1) {
834                 RTE_LOG(ERR, EAL, "Options -m and --"OPT_SOCKET_MEM" cannot "
835                         "be specified at the same time\n");
836                 return -1;
837         }
838         if (internal_cfg->no_hugetlbfs && internal_cfg->force_sockets == 1) {
839                 RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_MEM" cannot "
840                         "be specified together with --"OPT_NO_HUGE"\n");
841                 return -1;
842         }
843
844         if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
845                 rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
846                 RTE_LOG(ERR, EAL, "Options blacklist (-b) and whitelist (-w) "
847                         "cannot be used at the same time\n");
848                 return -1;
849         }
850
851         return 0;
852 }
853
854 void
855 eal_common_usage(void)
856 {
857         printf("[options]\n\n"
858                "EAL common options:\n"
859                "  -c COREMASK         Hexadecimal bitmask of cores to run on\n"
860                "  -l CORELIST         List of cores to run on\n"
861                "                      The argument format is <c1>[-c2][,c3[-c4],...]\n"
862                "                      where c1, c2, etc are core indexes between 0 and %d\n"
863                "  --"OPT_LCORES" COREMAP    Map lcore set to physical cpu set\n"
864                "                      The argument format is\n"
865                "                            '<lcores[@cpus]>[<,lcores[@cpus]>...]'\n"
866                "                      lcores and cpus list are grouped by '(' and ')'\n"
867                "                      Within the group, '-' is used for range separator,\n"
868                "                      ',' is used for single number separator.\n"
869                "                      '( )' can be omitted for single element group,\n"
870                "                      '@' can be omitted if cpus and lcores have the same value\n"
871                "  --"OPT_MASTER_LCORE" ID   Core ID that is used as master\n"
872                "  -n CHANNELS         Number of memory channels\n"
873                "  -m MB               Memory to allocate (see also --"OPT_SOCKET_MEM")\n"
874                "  -r RANKS            Force number of memory ranks (don't detect)\n"
875                "  -b, --"OPT_PCI_BLACKLIST" Add a PCI device in black list.\n"
876                "                      Prevent EAL from using this PCI device. The argument\n"
877                "                      format is <domain:bus:devid.func>.\n"
878                "  -w, --"OPT_PCI_WHITELIST" Add a PCI device in white list.\n"
879                "                      Only use the specified PCI devices. The argument format\n"
880                "                      is <[domain:]bus:devid.func>. This option can be present\n"
881                "                      several times (once per device).\n"
882                "                      [NOTE: PCI whitelist cannot be used with -b option]\n"
883                "  --"OPT_VDEV"              Add a virtual device.\n"
884                "                      The argument format is <driver><id>[,key=val,...]\n"
885                "                      (ex: --vdev=eth_pcap0,iface=eth2).\n"
886                "  --"OPT_VMWARE_TSC_MAP"    Use VMware TSC map instead of native RDTSC\n"
887                "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
888                "  --"OPT_SYSLOG"            Set syslog facility\n"
889                "  --"OPT_LOG_LEVEL"         Set default log level\n"
890                "  -v                  Display version information on startup\n"
891                "  -h, --help          This help\n"
892                "\nEAL options for DEBUG use only:\n"
893                "  --"OPT_NO_HUGE"           Use malloc instead of hugetlbfs\n"
894                "  --"OPT_NO_PCI"            Disable PCI\n"
895                "  --"OPT_NO_HPET"           Disable HPET\n"
896                "  --"OPT_NO_SHCONF"         No shared config (mmap'd files)\n"
897                "\n", RTE_MAX_LCORE);
898 }