eal/arm64: support ASan
[dpdk.git] / lib / eal / common / eal_common_options.c
index 6ecf5fd..1cfdd75 100644 (file)
@@ -223,9 +223,9 @@ eal_save_args(int argc, char **argv)
                return -1;
 
        for (i = 0; i < argc; i++) {
-               eal_args[i] = strdup(argv[i]);
                if (strcmp(argv[i], "--") == 0)
                        break;
+               eal_args[i] = strdup(argv[i]);
        }
        eal_args[i++] = NULL; /* always finish with NULL */
 
@@ -277,7 +277,7 @@ eal_option_device_parse(void)
        void *tmp;
        int ret = 0;
 
-       TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
+       RTE_TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
                if (ret == 0) {
                        ret = rte_devargs_add(devopt->type, devopt->arg);
                        if (ret)
@@ -703,10 +703,50 @@ update_lcore_config(int *cores)
        return ret;
 }
 
+static int
+check_core_list(int *lcores, unsigned int count)
+{
+       char lcorestr[RTE_MAX_LCORE * 10];
+       bool overflow = false;
+       int len = 0, ret;
+       unsigned int i;
+
+       for (i = 0; i < count; i++) {
+               if (lcores[i] < RTE_MAX_LCORE)
+                       continue;
+
+               RTE_LOG(ERR, EAL, "lcore %d >= RTE_MAX_LCORE (%d)\n",
+                       lcores[i], RTE_MAX_LCORE);
+               overflow = true;
+       }
+       if (!overflow)
+               return 0;
+
+       /*
+        * We've encountered a core that's greater than RTE_MAX_LCORE,
+        * suggest using --lcores option to map lcores onto physical cores
+        * greater than RTE_MAX_LCORE.
+        */
+       for (i = 0; i < count; i++) {
+               ret = snprintf(&lcorestr[len], sizeof(lcorestr) - len,
+                       "%d@%d,", i, lcores[i]);
+               if (ret > 0)
+                       len = len + ret;
+       }
+       if (len > 0)
+               lcorestr[len - 1] = 0;
+       RTE_LOG(ERR, EAL, "To use high physical core ids, "
+               "please use --lcores to map them to lcore ids below RTE_MAX_LCORE, "
+               "e.g. --lcores %s\n", lcorestr);
+       return -1;
+}
+
 static int
 eal_parse_coremask(const char *coremask, int *cores)
 {
-       unsigned count = 0;
+       const char *coremask_orig = coremask;
+       int lcores[RTE_MAX_LCORE];
+       unsigned int count = 0;
        int i, j, idx;
        int val;
        char c;
@@ -726,29 +766,52 @@ eal_parse_coremask(const char *coremask, int *cores)
        i = strlen(coremask);
        while ((i > 0) && isblank(coremask[i - 1]))
                i--;
-       if (i == 0)
+       if (i == 0) {
+               RTE_LOG(ERR, EAL, "No lcores in coremask: [%s]\n",
+                       coremask_orig);
                return -1;
+       }
 
-       for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
+       for (i = i - 1; i >= 0; i--) {
                c = coremask[i];
                if (isxdigit(c) == 0) {
                        /* invalid characters */
+                       RTE_LOG(ERR, EAL, "invalid characters in coremask: [%s]\n",
+                               coremask_orig);
                        return -1;
                }
                val = xdigit2val(c);
-               for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++)
+               for (j = 0; j < BITS_PER_HEX; j++, idx++)
                {
                        if ((1 << j) & val) {
-                               cores[idx] = count;
-                               count++;
+                               if (count >= RTE_MAX_LCORE) {
+                                       RTE_LOG(ERR, EAL, "Too many lcores provided. Cannot exceed RTE_MAX_LCORE (%d)\n",
+                                               RTE_MAX_LCORE);
+                                       return -1;
+                               }
+                               lcores[count++] = idx;
                        }
                }
        }
-       for (; i >= 0; i--)
-               if (coremask[i] != '0')
-                       return -1;
-       if (count == 0)
+       if (count == 0) {
+               RTE_LOG(ERR, EAL, "No lcores in coremask: [%s]\n",
+                       coremask_orig);
                return -1;
+       }
+
+       if (check_core_list(lcores, count))
+               return -1;
+
+       /*
+        * Now that we've got a list of cores no longer than RTE_MAX_LCORE,
+        * and no lcore in that list is greater than RTE_MAX_LCORE, populate
+        * the cores array.
+        */
+       do {
+               count--;
+               cores[lcores[count]] = count;
+       } while (count != 0);
+
        return 0;
 }
 
@@ -833,7 +896,8 @@ eal_parse_service_corelist(const char *corelist)
 static int
 eal_parse_corelist(const char *corelist, int *cores)
 {
-       unsigned count = 0;
+       unsigned int count = 0, i;
+       int lcores[RTE_MAX_LCORE];
        char *end = NULL;
        int min, max;
        int idx;
@@ -846,7 +910,7 @@ eal_parse_corelist(const char *corelist, int *cores)
                corelist++;
 
        /* Get list of cores */
-       min = RTE_MAX_LCORE;
+       min = -1;
        do {
                while (isblank(*corelist))
                        corelist++;
@@ -856,7 +920,7 @@ eal_parse_corelist(const char *corelist, int *cores)
                idx = strtol(corelist, &end, 10);
                if (errno || end == NULL)
                        return -1;
-               if (idx < 0 || idx >= RTE_MAX_LCORE)
+               if (idx < 0)
                        return -1;
                while (isblank(*end))
                        end++;
@@ -864,15 +928,26 @@ eal_parse_corelist(const char *corelist, int *cores)
                        min = idx;
                } else if ((*end == ',') || (*end == '\0')) {
                        max = idx;
-                       if (min == RTE_MAX_LCORE)
+                       if (min == -1)
                                min = idx;
                        for (idx = min; idx <= max; idx++) {
-                               if (cores[idx] == -1) {
-                                       cores[idx] = count;
-                                       count++;
+                               bool dup = false;
+
+                               /* Check if this idx is already present */
+                               for (i = 0; i < count; i++) {
+                                       if (lcores[i] == idx)
+                                               dup = true;
+                               }
+                               if (dup)
+                                       continue;
+                               if (count >= RTE_MAX_LCORE) {
+                                       RTE_LOG(ERR, EAL, "Too many lcores provided. Cannot exceed RTE_MAX_LCORE (%d)\n",
+                                               RTE_MAX_LCORE);
+                                       return -1;
                                }
+                               lcores[count++] = idx;
                        }
-                       min = RTE_MAX_LCORE;
+                       min = -1;
                } else
                        return -1;
                corelist = end + 1;
@@ -880,6 +955,20 @@ eal_parse_corelist(const char *corelist, int *cores)
 
        if (count == 0)
                return -1;
+
+       if (check_core_list(lcores, count))
+               return -1;
+
+       /*
+        * Now that we've got a list of cores no longer than RTE_MAX_LCORE,
+        * and no lcore in that list is greater than RTE_MAX_LCORE, populate
+        * the cores array.
+        */
+       do {
+               count--;
+               cores[lcores[count]] = count;
+       } while (count != 0);
+
        return 0;
 }