DPDK patches and discussions
 help / color / mirror / Atom feed
From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: david.marchand@redhat.com, mb@smartsharesystems.com,
	stephen@networkplumber.org,
	Bruce Richardson <bruce.richardson@intel.com>
Subject: [PATCH v3 4/4] eal: add option for auto-mapping cpu ids to low lcore ids
Date: Fri,  2 May 2025 16:11:34 +0100	[thread overview]
Message-ID: <20250502151134.536799-5-bruce.richardson@intel.com> (raw)
In-Reply-To: <20250502151134.536799-1-bruce.richardson@intel.com>

When attempting to run DPDK with cpu ids > RTE_MAX_LCORE, it can be
awkward to build up a command-line parameter specifying the cpu to lcore
mappings core-by-core. To simplify things for the common case, add in
the -L, --lcores-automap option, to take a list of cpu ids, which may or
may not be >= RTE_MAX_LCORE, and map them to lcore ids starting at zero.

For example, running lcores_autotest with dpdk-test on cores 140-143
with a build where RTE_MAX_LCORE is 128, is now as simple as:

  $ ./dpdk-test -L 140-143 -- lcores_autotest
  ...
  EAL threads count: 4, RTE_MAX_LCORE=128
  lcore 0, socket 1, role RTE, cpuset 140
  lcore 1, socket 1, role RTE, cpuset 141
  lcore 2, socket 1, role RTE, cpuset 142
  lcore 3, socket 1, role RTE, cpuset 143
  ...

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 doc/guides/linux_gsg/eal_args.include.rst | 16 +++++-
 lib/eal/common/eal_common_options.c       | 69 +++++++++++++++++++++--
 lib/eal/common/eal_options.h              |  2 +
 lib/eal/windows/include/sched.h           |  1 +
 4 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index d530215784..d8257fe8fc 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -34,6 +34,7 @@ Lcore-related options
 
     ``--lcores='1@31,2@32,3@33'``: Run threads having internal lcore ids of 1, 2 and 3,
     but with the threads being bound to physical CPUs 31, 32 and 33 respectively.
+    [See also the ``-L/--lcores-automap`` option below.]
 
     ``--lcores='(1-3)@(31-33)'``: Run three threads with lcore ids 1, 2 and 3.
     Unlike the previous example above,
@@ -50,9 +51,20 @@ Lcore-related options
     or deadlock when using DPDK rings or memory pools or spinlocks.
     Such a configuration should only be used with care.
 
+*   ``-L/--lcores-automap <core list>``
+
+    List of CPUs to run on, using lcore ids starting at 0.
+
+    Argument format is as <c1>[-c2][,c3[-c4],...]
+
+    One lcore thread will be spawned per cpu id specified,
+    and pinned to the specified cpu id, but with the lowest available lcore id.
+
+    This provides a convenient way to use CPU cores with ids greater than RTE_MAX_LCORE value.
+
 .. Note::
-    At a given instance only one core option ``--lcores``, ``-l`` or ``-c`` can
-    be used.
+    At a given instance only one core option ``--lcores``, ``-l``,
+    ``--lcores-automap``, ``-L`` or ``-c`` can be used.
 
 *   ``--main-lcore <core ID>``
 
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index ed514ec1d1..c77654c365 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -56,6 +56,7 @@ eal_short_options[] =
 	"d:" /* driver */
 	"h"  /* help */
 	"l:" /* corelist */
+	"L:" /* corelist with auto lcore id remapping */
 	"S:" /* service corelist */
 	"m:" /* memory size */
 	"n:" /* memory channels */
@@ -1223,6 +1224,52 @@ eal_parse_lcores(const char *lcores)
 	return ret;
 }
 
+static int
+eal_parse_remapped_lcores(const char *optarg)
+{
+	struct rte_config *cfg = rte_eal_get_configuration();
+	const size_t optarg_len = strlen(optarg);
+	rte_cpuset_t cpuset;
+
+	/* Reset lcore config */
+	for (unsigned int idx = 0; idx < RTE_MAX_LCORE; idx++) {
+		cfg->lcore_role[idx] = ROLE_OFF;
+		lcore_config[idx].core_index = -1;
+		CPU_ZERO(&lcore_config[idx].cpuset);
+	}
+
+	/* the eal_parse_set API only handles "," within (), so wrap string */
+	char *tmp_optarg = malloc(optarg_len + 3);
+	if (tmp_optarg == NULL) {
+		EAL_LOG(ERR, "Error with malloc for temporary optarg string");
+		return -1;
+	}
+	snprintf(tmp_optarg, optarg_len + 3, "(%s)", optarg);
+
+	/* parse wrapped string */
+	int parsed_chars = eal_parse_set(tmp_optarg, &cpuset);
+	free(tmp_optarg);
+	if (parsed_chars == -1 || CPU_COUNT(&cpuset) == 0) {
+		EAL_LOG(ERR, "Invalid corelist for remapping: %s", optarg);
+		return -1;
+	}
+
+	unsigned int lcore_id = 0;
+	unsigned int cpu_id = 0;
+	while (CPU_COUNT(&cpuset) > 0) {
+		if (CPU_ISSET(cpu_id, &cpuset)) {
+			cfg->lcore_role[lcore_id] = ROLE_RTE;
+			lcore_config[lcore_id].core_index = lcore_id;
+			CPU_SET(cpu_id, &lcore_config[lcore_id].cpuset);
+			CPU_CLR(cpu_id, &cpuset);
+			lcore_id++;
+		}
+		cpu_id++;
+	}
+
+	return 0;
+}
+
 static void
 eal_log_usage(void)
 {
@@ -1634,21 +1681,25 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 	}
 	/* corelist */
+	case 'L':
 	case 'l': {
 		if (eal_service_cores_parsed())
 			EAL_LOG(WARNING,
 				"Service cores parsed before dataplane cores. Please ensure -l is before -s or -S");
 
-		if (eal_parse_lcores(optarg) < 0) {
-			EAL_LOG(ERR, "invalid parameter for -l/--" OPT_LCORES);
+		int retval = opt == 'l' ?
+			eal_parse_lcores(optarg) :
+			eal_parse_remapped_lcores(optarg);
+		if (retval < 0) {
+			EAL_LOG(ERR, "invalid parameter for lcore list option: '%s'", optarg);
 			return -1;
 		}
 
 		if (core_parsed) {
 			if (core_parsed == LCORE_OPT_LST)
-				EAL_LOG(ERR, "Core list option passed multiple times to EAL");
+				EAL_LOG(ERR, "Multiple core list options passed to EAL");
 			else
-				EAL_LOG(ERR, "Option '-l/--lcores' is ignored, because coremask option used");
+				EAL_LOG(ERR, "Core list option is ignored, because coremask option used");
 			return -1;
 		}
 
@@ -2118,6 +2169,14 @@ eal_common_usage(void)
 	       "                      ',' is used for single number separator.\n"
 	       "                      '( )' can be omitted for single element group,\n"
 	       "                      '@' can be omitted if cpus and lcores have the same value\n"
+	       "  -L, --"OPT_LCORES_AUTOMAP" CORELIST\n"
+	       "                      List of CPUs to run on, using lcore ids starting at 0.\n"
+	       "                      Argument format is as <c1>[-c2][,c3[-c4],...]\n"
+	       "                      One lcore thread will be spawned per cpu id specified,\n"
+	       "                      and pinned to the specified cpu id, but with the lowest\n"
+	       "                      available lcore id.\n"
+	       "                      This provides a convenient way to use CPU cores with ids\n"
+	       "                      greater than RTE_MAX_LCORE value (%d)\n"
 	       "  -s SERVICE COREMASK Hexadecimal bitmask of cores to be used as service cores\n"
 	       "  --"OPT_MAIN_LCORE" ID     Core ID that is used as main\n"
 	       "  --"OPT_MBUF_POOL_OPS_NAME" Pool ops name for mbuf to use\n"
@@ -2191,5 +2250,5 @@ eal_common_usage(void)
 	       "  --"OPT_NO_PCI"            Disable PCI\n"
 	       "  --"OPT_NO_HPET"           Disable HPET\n"
 	       "  --"OPT_NO_SHCONF"         No shared config (mmap'd files)\n"
-	       "\n", RTE_MAX_LCORE);
+	       "\n", RTE_MAX_LCORE, RTE_MAX_LCORE);
 }
diff --git a/lib/eal/common/eal_options.h b/lib/eal/common/eal_options.h
index 7b84b7d778..cdea876635 100644
--- a/lib/eal/common/eal_options.h
+++ b/lib/eal/common/eal_options.h
@@ -19,6 +19,8 @@ enum {
 	OPT_DEV_BLOCK_NUM      = 'b',
 #define OPT_LCORES            "lcores"
 	OPT_LCORES_NUM         = 'l',
+#define OPT_LCORES_AUTOMAP    "lcores-automap"
+	OPT_LCORES_AUTOMAP_NUM = 'L',
 
 	/* first long only option value must be >= 256, so that we won't
 	 * conflict with short options */
diff --git a/lib/eal/windows/include/sched.h b/lib/eal/windows/include/sched.h
index 912fed12c2..04ee046bb7 100644
--- a/lib/eal/windows/include/sched.h
+++ b/lib/eal/windows/include/sched.h
@@ -31,6 +31,7 @@ typedef struct _rte_cpuset_s {
 #define RTE_HAS_CPUSET
 
 #define CPU_SET(b, s) ((s)->_bits[_WHICH_SET(b)] |= (1LL << _WHICH_BIT(b)))
+#define CPU_CLR(b, s) ((s)->_bits[_WHICH_SET(b)] &= ~(1LL << _WHICH_BIT(b)))
 
 #define CPU_ZERO(s)							\
 	do {								\
-- 
2.45.2


      parent reply	other threads:[~2025-05-02 15:12 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-13 11:38 [RFC PATCH 0/3] allow easier use of high lcore-ids Bruce Richardson
2025-03-13 11:38 ` [RFC PATCH 1/3] eal: centralize core parameter parsing Bruce Richardson
2025-03-13 11:38 ` [RFC PATCH 2/3] eal: convert core masks and lists to core sets Bruce Richardson
2025-03-13 11:38 ` [RFC PATCH 3/3] eal: allow automatic mapping of high lcore ids Bruce Richardson
2025-03-24 17:30 ` [PATCH v2 0/3] allow easier use of high lcore-ids Bruce Richardson
2025-03-24 17:30   ` [PATCH v2 1/3] eal: centralize core parameter parsing Bruce Richardson
2025-04-07  6:58     ` David Marchand
2025-03-24 17:30   ` [PATCH v2 2/3] eal: convert core masks and lists to core sets Bruce Richardson
2025-04-07  6:59     ` David Marchand
2025-03-24 17:30   ` [PATCH v2 3/3] eal: allow automatic mapping of high lcore ids Bruce Richardson
2025-04-01 14:06   ` [PATCH v2 0/3] allow easier use of high lcore-ids Bruce Richardson
2025-04-07  7:04     ` David Marchand
2025-04-07  9:48       ` Bruce Richardson
2025-04-07 10:15         ` Morten Brørup
2025-04-07 10:40           ` Bruce Richardson
2025-04-07 11:32             ` Morten Brørup
2025-04-07 11:56               ` Bruce Richardson
2025-04-07 12:25                 ` Morten Brørup
2025-04-07 12:41                   ` Bruce Richardson
2025-04-07 13:18                     ` Morten Brørup
2025-04-07 13:24                       ` Bruce Richardson
2025-04-07 15:14           ` Stephen Hemminger
2025-04-07 15:38             ` Bruce Richardson
2025-05-02 15:11 ` [PATCH v3 0/4] rework and expand EAL lcore options Bruce Richardson
2025-05-02 15:11   ` [PATCH v3 1/4] eal: deprecate old coremask-based EAL parameters Bruce Richardson
2025-05-02 15:51     ` Stephen Hemminger
2025-05-02 16:00       ` Bruce Richardson
2025-05-03  6:09         ` Morten Brørup
2025-05-02 15:11   ` [PATCH v3 2/4] eal: merge corelist and core mapping options Bruce Richardson
2025-05-02 15:11   ` [PATCH v3 3/4] doc: provide examples of using lcores EAL parameter Bruce Richardson
2025-05-02 15:11   ` Bruce Richardson [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250502151134.536799-5-bruce.richardson@intel.com \
    --to=bruce.richardson@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=mb@smartsharesystems.com \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).