New upstream version 18.08
[deb_dpdk.git] / lib / librte_eal / common / eal_common_options.c
index 9f2f8d2..dd5f974 100644 (file)
@@ -27,6 +27,7 @@
 #include "eal_internal_cfg.h"
 #include "eal_options.h"
 #include "eal_filesystem.h"
+#include "eal_private.h"
 
 #define BITS_PER_HEX 4
 #define LCORE_OPT_LST 1
@@ -65,14 +66,18 @@ eal_long_options[] = {
        {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
        {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
        {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
+       {OPT_IN_MEMORY,         0, NULL, OPT_IN_MEMORY_NUM        },
        {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
        {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
        {OPT_PROC_TYPE,         1, NULL, OPT_PROC_TYPE_NUM        },
        {OPT_SOCKET_MEM,        1, NULL, OPT_SOCKET_MEM_NUM       },
+       {OPT_SOCKET_LIMIT,      1, NULL, OPT_SOCKET_LIMIT_NUM     },
        {OPT_SYSLOG,            1, NULL, OPT_SYSLOG_NUM           },
        {OPT_VDEV,              1, NULL, OPT_VDEV_NUM             },
        {OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
        {OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
+       {OPT_LEGACY_MEM,        0, NULL, OPT_LEGACY_MEM_NUM       },
+       {OPT_SINGLE_FILE_SEGMENTS, 0, NULL, OPT_SINGLE_FILE_SEGMENTS_NUM},
        {0,                     0, NULL, 0                        }
 };
 
@@ -151,7 +156,7 @@ eal_option_device_parse(void)
 
        TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
                if (ret == 0) {
-                       ret = rte_eal_devargs_add(devopt->type, devopt->arg);
+                       ret = rte_devargs_add(devopt->type, devopt->arg);
                        if (ret)
                                RTE_LOG(ERR, EAL, "Unable to parse device '%s'\n",
                                        devopt->arg);
@@ -176,9 +181,16 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
        /* zero out the NUMA config */
        for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
                internal_cfg->socket_mem[i] = 0;
+       internal_cfg->force_socket_limits = 0;
+       /* zero out the NUMA limits config */
+       for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
+               internal_cfg->socket_limit[i] = 0;
        /* zero out hugedir descriptors */
-       for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
+       for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) {
+               memset(&internal_cfg->hugepage_info[i], 0,
+                               sizeof(internal_cfg->hugepage_info[0]));
                internal_cfg->hugepage_info[i].lock_descriptor = -1;
+       }
        internal_cfg->base_virtaddr = 0;
 
        internal_cfg->syslog_facility = LOG_DAEMON;
@@ -194,6 +206,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
        internal_cfg->vmware_tsc_map = 0;
        internal_cfg->create_uio_dev = 0;
        internal_cfg->user_mbuf_pool_ops_name = NULL;
+       internal_cfg->init_complete = 0;
 }
 
 static int
@@ -308,6 +321,7 @@ eal_parse_service_coremask(const char *coremask)
        unsigned int count = 0;
        char c;
        int val;
+       uint32_t taken_lcore_count = 0;
 
        if (coremask == NULL)
                return -1;
@@ -341,7 +355,7 @@ eal_parse_service_coremask(const char *coremask)
                                if (master_lcore_parsed &&
                                                cfg->master_lcore == lcore) {
                                        RTE_LOG(ERR, EAL,
-                                               "Error: lcore %u is master lcore, cannot use as service core\n",
+                                               "lcore %u is master lcore, cannot use as service core\n",
                                                idx);
                                        return -1;
                                }
@@ -351,6 +365,10 @@ eal_parse_service_coremask(const char *coremask)
                                                "lcore %u unavailable\n", idx);
                                        return -1;
                                }
+
+                               if (cfg->lcore_role[idx] == ROLE_RTE)
+                                       taken_lcore_count++;
+
                                lcore_config[idx].core_role = ROLE_SERVICE;
                                count++;
                        }
@@ -367,10 +385,27 @@ eal_parse_service_coremask(const char *coremask)
        if (count == 0)
                return -1;
 
+       if (core_parsed && taken_lcore_count != count) {
+               RTE_LOG(WARNING, EAL,
+                       "Not all service cores are in the coremask. "
+                       "Please ensure -c or -l includes service cores\n");
+       }
+
        cfg->service_lcore_count = count;
        return 0;
 }
 
+static int
+eal_service_cores_parsed(void)
+{
+       int idx;
+       for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
+               if (lcore_config[idx].core_role == ROLE_SERVICE)
+                       return 1;
+       }
+       return 0;
+}
+
 static int
 eal_parse_coremask(const char *coremask)
 {
@@ -380,6 +415,11 @@ eal_parse_coremask(const char *coremask)
        char c;
        int val;
 
+       if (eal_service_cores_parsed())
+               RTE_LOG(WARNING, EAL,
+                       "Service cores parsed before dataplane cores. "
+                       "Please ensure -c is before -s or -S\n");
+
        if (coremask == NULL)
                return -1;
        /* Remove all blank characters ahead and after .
@@ -411,6 +451,7 @@ eal_parse_coremask(const char *coremask)
                                                "unavailable\n", idx);
                                        return -1;
                                }
+
                                cfg->lcore_role[idx] = ROLE_RTE;
                                lcore_config[idx].core_index = count;
                                count++;
@@ -442,6 +483,7 @@ eal_parse_service_corelist(const char *corelist)
        unsigned count = 0;
        char *end = NULL;
        int min, max;
+       uint32_t taken_lcore_count = 0;
 
        if (corelist == NULL)
                return -1;
@@ -483,6 +525,9 @@ eal_parse_service_corelist(const char *corelist)
                                                        idx);
                                                return -1;
                                        }
+                                       if (cfg->lcore_role[idx] == ROLE_RTE)
+                                               taken_lcore_count++;
+
                                        lcore_config[idx].core_role =
                                                        ROLE_SERVICE;
                                        count++;
@@ -497,6 +542,12 @@ eal_parse_service_corelist(const char *corelist)
        if (count == 0)
                return -1;
 
+       if (core_parsed && taken_lcore_count != count) {
+               RTE_LOG(WARNING, EAL,
+                       "Not all service cores were in the coremask. "
+                       "Please ensure -c or -l includes service cores\n");
+       }
+
        return 0;
 }
 
@@ -509,6 +560,11 @@ eal_parse_corelist(const char *corelist)
        char *end = NULL;
        int min, max;
 
+       if (eal_service_cores_parsed())
+               RTE_LOG(WARNING, EAL,
+                       "Service cores parsed before dataplane cores. "
+                       "Please ensure -l is before -s or -S\n");
+
        if (corelist == NULL)
                return -1;
 
@@ -583,7 +639,8 @@ eal_parse_master_lcore(const char *arg)
 
        /* ensure master core is not used as service core */
        if (lcore_config[cfg->master_lcore].core_role == ROLE_SERVICE) {
-               RTE_LOG(ERR, EAL, "Error: Master lcore is used as a service core.\n");
+               RTE_LOG(ERR, EAL,
+                       "Error: Master lcore is used as a service core\n");
                return -1;
        }
 
@@ -875,7 +932,7 @@ static int
 eal_parse_syslog(const char *facility, struct internal_config *conf)
 {
        int i;
-       static struct {
+       static const struct {
                const char *name;
                int value;
        } map[] = {
@@ -911,43 +968,92 @@ eal_parse_syslog(const char *facility, struct internal_config *conf)
 }
 
 static int
-eal_parse_log_level(const char *arg)
+eal_parse_log_priority(const char *level)
 {
-       char *end, *str, *type, *level;
+       static const char * const levels[] = {
+               [RTE_LOG_EMERG]   = "emergency",
+               [RTE_LOG_ALERT]   = "alert",
+               [RTE_LOG_CRIT]    = "critical",
+               [RTE_LOG_ERR]     = "error",
+               [RTE_LOG_WARNING] = "warning",
+               [RTE_LOG_NOTICE]  = "notice",
+               [RTE_LOG_INFO]    = "info",
+               [RTE_LOG_DEBUG]   = "debug",
+       };
+       size_t len = strlen(level);
        unsigned long tmp;
+       char *end;
+       unsigned int i;
 
-       str = strdup(arg);
-       if (str == NULL)
+       if (len == 0)
                return -1;
 
-       if (strchr(str, ',') == NULL) {
-               type = NULL;
-               level = str;
-       } else {
-               type = strsep(&str, ",");
-               level = strsep(&str, ",");
+       /* look for named values, skip 0 which is not a valid level */
+       for (i = 1; i < RTE_DIM(levels); i++) {
+               if (strncmp(levels[i], level, len) == 0)
+                       return i;
        }
 
+       /* not a string, maybe it is numeric */
        errno = 0;
        tmp = strtoul(level, &end, 0);
 
        /* check for errors */
-       if ((errno != 0) || (level[0] == '\0') ||
-                   end == NULL || (*end != '\0'))
-               goto fail;
+       if (errno != 0 || end == NULL || *end != '\0' ||
+           tmp >= UINT32_MAX)
+               return -1;
 
-       /* log_level is a uint32_t */
-       if (tmp >= UINT32_MAX)
-               goto fail;
+       return tmp;
+}
+
+static int
+eal_parse_log_level(const char *arg)
+{
+       const char *pattern = NULL;
+       const char *regex = NULL;
+       char *str, *level;
+       int priority;
+
+       str = strdup(arg);
+       if (str == NULL)
+               return -1;
 
-       if (type == NULL) {
-               rte_log_set_global_level(tmp);
-       } else if (rte_log_set_level_regexp(type, tmp) < 0) {
-               printf("cannot set log level %s,%lu\n",
-                       type, tmp);
+       if ((level = strchr(str, ','))) {
+               regex = str;
+               *level++ = '\0';
+       } else if ((level = strchr(str, ':'))) {
+               pattern = str;
+               *level++ = '\0';
+       } else {
+               level = str;
+       }
+
+       priority = eal_parse_log_priority(level);
+       if (priority < 0) {
+               fprintf(stderr, "invalid log priority: %s\n", level);
                goto fail;
        }
 
+       if (regex) {
+               if (rte_log_set_level_regexp(regex, priority) < 0) {
+                       fprintf(stderr, "cannot set log level %s,%d\n",
+                               pattern, priority);
+                       goto fail;
+               }
+               if (rte_log_save_regexp(regex, priority) < 0)
+                       goto fail;
+       } else if (pattern) {
+               if (rte_log_set_level_pattern(pattern, priority) < 0) {
+                       fprintf(stderr, "cannot set log level %s:%d\n",
+                               pattern, priority);
+                       goto fail;
+               }
+               if (rte_log_save_pattern(pattern, priority) < 0)
+                       goto fail;
+       } else {
+               rte_log_set_global_level(priority);
+       }
+
        free(str);
        return 0;
 
@@ -1089,6 +1195,8 @@ eal_parse_common_option(int opt, const char *optarg,
 
        case OPT_NO_HUGE_NUM:
                conf->no_hugetlbfs = 1;
+               /* no-huge is legacy mem */
+               conf->legacy_mem = 1;
                break;
 
        case OPT_NO_PCI_NUM:
@@ -1107,6 +1215,13 @@ eal_parse_common_option(int opt, const char *optarg,
                conf->no_shconf = 1;
                break;
 
+       case OPT_IN_MEMORY_NUM:
+               conf->in_memory = 1;
+               /* in-memory is a superset of noshconf and huge-unlink */
+               conf->no_shconf = 1;
+               conf->hugepage_unlink = 1;
+               break;
+
        case OPT_PROC_TYPE_NUM:
                conf->process_type = eal_parse_proc_type(optarg);
                break;
@@ -1160,6 +1275,12 @@ eal_parse_common_option(int opt, const char *optarg,
 
                core_parsed = LCORE_OPT_MAP;
                break;
+       case OPT_LEGACY_MEM_NUM:
+               conf->legacy_mem = 1;
+               break;
+       case OPT_SINGLE_FILE_SEGMENTS_NUM:
+               conf->single_file_segments = 1;
+               break;
 
        /* don't know what to do, leave this to caller */
        default:
@@ -1252,12 +1373,23 @@ eal_check_common_options(struct internal_config *internal_cfg)
                        "be specified together with --"OPT_NO_HUGE"\n");
                return -1;
        }
-
-       if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink) {
+       if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink &&
+                       !internal_cfg->in_memory) {
                RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
                        "be specified together with --"OPT_NO_HUGE"\n");
                return -1;
        }
+       if (internal_config.force_socket_limits && internal_config.legacy_mem) {
+               RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_LIMIT
+                       " is only supported in non-legacy memory mode\n");
+       }
+       if (internal_cfg->single_file_segments &&
+                       internal_cfg->hugepage_unlink) {
+               RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE_SEGMENTS" is "
+                       "not compatible with neither --"OPT_IN_MEMORY" nor "
+                       "--"OPT_HUGE_UNLINK"\n");
+               return -1;
+       }
 
        return 0;
 }
@@ -1302,10 +1434,12 @@ eal_common_usage(void)
               "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
               "  --"OPT_SYSLOG"            Set syslog facility\n"
               "  --"OPT_LOG_LEVEL"=<int>   Set global log level\n"
-              "  --"OPT_LOG_LEVEL"=<type-regexp>,<int>\n"
+              "  --"OPT_LOG_LEVEL"=<type-match>:<int>\n"
               "                      Set specific log level\n"
               "  -v                  Display version information on startup\n"
               "  -h, --help          This help\n"
+              "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
+              "                      disable secondary process support\n"
               "\nEAL options for DEBUG use only:\n"
               "  --"OPT_HUGE_UNLINK"       Unlink hugepage files after init\n"
               "  --"OPT_NO_HUGE"           Use malloc instead of hugetlbfs\n"