eal: suggest using --lcores option
authorDavid Hunt <david.hunt@intel.com>
Wed, 3 Nov 2021 14:32:28 +0000 (14:32 +0000)
committerDavid Marchand <david.marchand@redhat.com>
Fri, 5 Nov 2021 13:39:37 +0000 (14:39 +0100)
If the user requests to use an lcore above 128 using -l,
the eal will exit with "EAL: invalid core list syntax" and
very little else useful information.

This patch adds some extra information suggesting to use --lcores
so that physical cores above RTE_MAX_LCORE (default 128) can be
used. This is achieved by using the --lcores option by mapping
the logical cores in the application to physical cores.

For example, if "-l 12-16,130,132" is used, we see the following
additional output on the command line:

EAL: lcore 132 >= RTE_MAX_LCORE (128)
EAL: lcore 133 >= RTE_MAX_LCORE (128)
EAL: To use high physical core ids, please use --lcores to map them
to lcore ids below RTE_MAX_LCORE,
EAL: e.g. --lcores 0@12,1@13,2@14,3@15,4@16,5@132,6@133

The same is added to -c option parsing.

For example, if "-c 0x300000000000000000000000000000000" is
used, we see the following additional output on the command line:

EAL: lcore 128 >= RTE_MAX_LCORE (128)
EAL: lcore 129 >= RTE_MAX_LCORE (128)
EAL: To use high physical core ids, please use --lcores to map them
to lcore ids below RTE_MAX_LCORE,
EAL: e.g. --lcores 0@128,1@129

Signed-off-by: David Hunt <david.hunt@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
lib/eal/common/eal_common_options.c

index 1802e3d..1cfdd75 100644 (file)
@@ -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;
 }