From bb0bd346d5c130350be3fe019cd48ecbbe50ab90 Mon Sep 17 00:00:00 2001 From: David Hunt Date: Wed, 3 Nov 2021 14:32:28 +0000 Subject: [PATCH] eal: suggest using --lcores option 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 Acked-by: Bruce Richardson --- lib/eal/common/eal_common_options.c | 125 ++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 18 deletions(-) diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index 1802e3d9e1..1cfdd75f3b 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -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; }