DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: techboard@dpdk.org, Bruce Richardson <bruce.richardson@intel.com>
Subject: [RFC PATCH 38/44] eal_cfg: configure defaults for easier testing and use
Date: Wed, 29 Apr 2026 17:58:30 +0100	[thread overview]
Message-ID: <20260429165845.2136843-39-bruce.richardson@intel.com> (raw)
In-Reply-To: <20260429165845.2136843-1-bruce.richardson@intel.com>

Add a function to configure the lcore settings with the current thread
affinities. Use that function when EAL is being initialized without any
lcores otherwise being specified. This minics existing DPDK behaviour
when no "-l" or "-c" flags are passed on EAL commandline. Also set the
"in-memory" flag by default, which makes testing easier, and should be a
sensible default for most app cases except when multi-process is
required.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 lib/eal_cfg/eal_cfg.c     | 91 ++++++++++++++++++++++++++++++++++++---
 lib/eal_cfg/rte_eal_cfg.h | 48 ++++++++++++++++++++-
 2 files changed, 133 insertions(+), 6 deletions(-)

diff --git a/lib/eal_cfg/eal_cfg.c b/lib/eal_cfg/eal_cfg.c
index 70f0122b81..18a508e7ad 100644
--- a/lib/eal_cfg/eal_cfg.c
+++ b/lib/eal_cfg/eal_cfg.c
@@ -7,7 +7,9 @@
 
 #include <eal_export.h>
 #include <rte_errno.h>
+#include <rte_lcore.h>
 #include <rte_log.h>
+#include <rte_thread.h>
 
 #include "eal_internal_cfg.h"
 #include "rte_eal_cfg.h"
@@ -29,6 +31,9 @@ rte_eal_cfg_create(void)
 	}
 
 	cfg->user_cfg = EAL_USER_CFG_INITIALIZER(cfg->user_cfg);
+	/* default to in-memory mode without a shared config */
+	cfg->user_cfg.in_memory = true;
+	cfg->user_cfg.no_shconf = true;
 
 	return cfg;
 }
@@ -44,21 +49,97 @@ rte_eal_cfg_free(struct rte_eal_cfg *cfg)
 	free(cfg);
 }
 
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eal_cfg_set_lcores_from_affinity, 26.07)
+int
+rte_eal_cfg_set_lcores_from_affinity(struct rte_eal_cfg *cfg, bool remap)
+{
+	rte_cpuset_t cpuset;
+	unsigned int lcore_id = 0;
+	int count = 0;
+
+	if (cfg == NULL) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	if (rte_thread_get_affinity_by_id(rte_thread_self(), &cpuset) != 0) {
+		rte_errno = ENOTSUP;
+		return -1;
+	}
+
+	/* clear any existing lcore configuration before populating */
+	for (unsigned int i = 0; i < RTE_MAX_LCORE; i++) {
+		free(cfg->user_cfg.lcore_cpusets[i]);
+		cfg->user_cfg.lcore_cpusets[i] = NULL;
+	}
+
+	for (unsigned int cpu = 0; cpu < CPU_SETSIZE; cpu++) {
+		if (!CPU_ISSET(cpu, &cpuset))
+			continue;
+		if (!remap)
+			lcore_id = cpu;
+		if (lcore_id >= RTE_MAX_LCORE)
+			break;
+		cfg->user_cfg.lcore_cpusets[lcore_id] = malloc(sizeof(rte_cpuset_t));
+		if (cfg->user_cfg.lcore_cpusets[lcore_id] == NULL) {
+			for (unsigned int i = 0; i < lcore_id; i++) {
+				free(cfg->user_cfg.lcore_cpusets[i]);
+				cfg->user_cfg.lcore_cpusets[i] = NULL;
+			}
+			rte_errno = ENOMEM;
+			return -1;
+		}
+		CPU_ZERO(cfg->user_cfg.lcore_cpusets[lcore_id]);
+		CPU_SET(cpu, cfg->user_cfg.lcore_cpusets[lcore_id]);
+		count++;
+		lcore_id++;
+	}
+
+	if (count == 0) {
+		rte_errno = ENOTSUP;
+		return -1;
+	}
+
+	return 0;
+}
+
 RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_eal_init_from_cfg, 26.07)
 int
 rte_eal_init_from_cfg(const char *progname, struct rte_eal_cfg *cfg)
 {
-	struct rte_eal_cfg local_cfg = {
-		.user_cfg = EAL_USER_CFG_INITIALIZER(local_cfg.user_cfg),
-	};
+	unsigned int i;
 
 	if (progname == NULL || progname[0] == '\0') {
 		rte_errno = EINVAL;
 		return -1;
 	}
 
-	if (cfg == NULL)
-		cfg = &local_cfg;
+	if (cfg == NULL) {
+		struct rte_eal_cfg local_cfg = {
+			.user_cfg = EAL_USER_CFG_INITIALIZER(local_cfg.user_cfg),
+		};
+		local_cfg.user_cfg.in_memory = true;
+		local_cfg.user_cfg.no_shconf = true;
+		if (rte_eal_cfg_set_lcores_from_affinity(&local_cfg, true) < 0) {
+			eal_user_cfg_cleanup(&local_cfg.user_cfg);
+			return -1;
+		}
+
+		int ret = rte_eal_runtime_init(progname, &local_cfg.user_cfg);
+		eal_user_cfg_cleanup(&local_cfg.user_cfg);
+		return ret;
+	}
+
+	/* If no lcores have been configured, default to the current thread's
+	 * CPU affinity, matching rte_eal_init() behaviour when neither -c nor
+	 * -l is passed.
+	 */
+	for (i = 0; i < RTE_MAX_LCORE; i++) {
+		if (cfg->user_cfg.lcore_cpusets[i] != NULL)
+			break;
+	}
+	if (i == RTE_MAX_LCORE && rte_eal_cfg_set_lcores_from_affinity(cfg, true) < 0)
+		return -1;
 
 	return rte_eal_runtime_init(progname, &cfg->user_cfg);
 }
diff --git a/lib/eal_cfg/rte_eal_cfg.h b/lib/eal_cfg/rte_eal_cfg.h
index c0d316a6cb..ecabe136d8 100644
--- a/lib/eal_cfg/rte_eal_cfg.h
+++ b/lib/eal_cfg/rte_eal_cfg.h
@@ -19,6 +19,8 @@
 extern "C" {
 #endif
 
+#include <stdbool.h>
+
 #include <rte_compat.h>
 
 /**
@@ -32,6 +34,11 @@ struct rte_eal_cfg;
  * Allocates and initialises a configuration struct with default values
  * equivalent to those used when rte_eal_init() is called with no options.
  *
+ * Returned defaults include:
+ *   - empty lcore configuration (no lcores configured)
+ *   - in-memory mode enabled, which disables multi-process mode,
+ *     but allows multiple identical application instances to run concurrently.
+ *
  * @return
  *   Pointer to a new configuration handle, or NULL on failure (rte_errno set).
  */
@@ -51,13 +58,52 @@ __rte_experimental
 void
 rte_eal_cfg_free(struct rte_eal_cfg *cfg);
 
+/**
+ * Populate lcore configuration from the calling thread's CPU affinity.
+ *
+ * Queries the current thread's CPU affinity and replaces the lcore
+ * configuration in @p cfg with one DPDK lcore per CPU in the affinity
+ * set. Any existing lcore configuration in the handle is cleared before
+ * the new mapping is applied.
+ *
+ * When @p remap is false, an identity mapping is used: lcore ID equals
+ * the physical CPU number. CPUs with numbers at or above RTE_MAX_LCORE
+ * are silently skipped. This matches the behaviour of rte_eal_init()
+ * when neither -c nor -l is passed on the command line.
+ *
+ * When @p remap is true, lcore IDs are assigned sequentially starting
+ * from 0 regardless of physical CPU numbers, so CPUs above RTE_MAX_LCORE
+ * are usable as long as the total count stays within RTE_MAX_LCORE.
+ *
+ * rte_eal_init_from_cfg() calls this automatically with @p remap set to
+ * true when no lcores have been configured in the handle.
+ *
+ * @param cfg
+ *   Configuration handle created with rte_eal_cfg_create(). Must not be NULL.
+ * @param remap
+ *   If true, assign sequential lcore IDs (0, 1, 2, ...) to affinitised CPUs.
+ *   If false, use identity mapping (lcore ID == physical CPU ID).
+ * @return
+ *   0 on success, or -1 on failure (rte_errno is set to EINVAL if cfg is NULL,
+ *   ENOTSUP if the affinity could not be queried or yielded no usable CPUs,
+ *   or ENOMEM on allocation failure).
+ */
+__rte_experimental
+int
+rte_eal_cfg_set_lcores_from_affinity(struct rte_eal_cfg *cfg, bool remap);
+
 /**
  * Initialise the EAL using a programmatic configuration handle.
  *
  * This function is a programmatic alternative to rte_eal_init().
  * The caller optionally creates a configuration handle with rte_eal_cfg_create(),
  * populates it via setter functions, and passes it to this function
- * in place of argc/argv. If @p cfg is NULL, default EAL configuration is used.
+ * in place of argc/argv.
+ *
+ * If @p cfg is NULL, default EAL configuration is used, where:
+ *   - lcores are assigned based on the current thread's CPU affinity
+ *   - in-memory mode is enabled, which disables multi-process mode,
+ *     but allows multiple identical application instances to run concurrently.
  *
  * @param progname
  *   The program name, used for logging. Must not be NULL or empty.
-- 
2.51.0


  parent reply	other threads:[~2026-04-29 17:04 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-29 16:57 [RFC PATCH 00/44] Allow intitializing EAL without argc/argv Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 01/44] eal: define new functionally distinct config structs Bruce Richardson
2026-04-29 19:03   ` Stephen Hemminger
2026-04-30  7:56     ` Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 02/44] eal: move memory request fields to user config Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 03/44] eal: move NUMA " Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 04/44] eal: move hugepage policy " Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 05/44] eal: move process " Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 06/44] eal: move advanced user config options to user cfg struct Bruce Richardson
2026-04-29 16:57 ` [RFC PATCH 07/44] eal: move hugepage size info to platform info struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 08/44] telemetry: make cpuset init parameter const Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 09/44] eal: move runtime state to appropriate structure Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 10/44] eal: record details of all cpus in platform info Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 11/44] eal: use platform info for lcore lookups Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 12/44] eal: add RTE_CPU_FFS macro Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 13/44] eal: store lcore configuration in runtime data Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 14/44] eal: cleanup CPU init function Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 15/44] eal: move numa node information to platform info struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 16/44] eal: move lcore role and count to runtime state Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 17/44] eal: make lcore role a field in lcore config struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 18/44] eal: move main lcore setting to runtime " Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 19/44] eal: move iova mode and process type to runtime cfg Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 20/44] eal: move memory config pointer to runtime state struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 21/44] eal: remove rte_config structure Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 22/44] eal: separate runtime state update from arg parsing Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 23/44] eal: move devopt_list staging list into user_cfg Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 24/44] eal: separate plugin paths from loaded plugin objects Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 25/44] eal: simplify internal driver path iteration APIs Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 26/44] eal: move trace config into user config struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 27/44] eal: record service cores in " Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 28/44] eal: store user-provided lcore info " Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 29/44] eal: clarify docs on params taking lcore IDs Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 30/44] eal: remove internal config reset function Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 31/44] eal: move functions setting runtime state Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 32/44] eal: initialize platform info on first use Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 33/44] eal: remove duplicated scan of sysfs for hugepage details Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 34/44] eal: add utilities for working with user config struct Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 35/44] eal: split EAL init into two stages Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 36/44] eal: provide hooks for init with externally supplied config Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 37/44] eal_cfg: add new library to programmatically init DPDK Bruce Richardson
2026-04-29 16:58 ` Bruce Richardson [this message]
2026-04-29 16:58 ` [RFC PATCH 39/44] app/test: enable testing init using EAL config lib Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 40/44] eal_cfg: add basic setters and getters Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 41/44] eal_cfg: add hugepage memory configuration Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 42/44] eal_cfg: support configuring lcores Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 43/44] eal_cfg: support device and driver lists Bruce Richardson
2026-04-29 16:58 ` [RFC PATCH 44/44] eal_cfg: add APIs for configuring remaining init settings Bruce Richardson
2026-04-29 21:40 ` [RFC PATCH 00/44] Allow intitializing EAL without argc/argv Stephen Hemminger
2026-04-29 22:04 ` Stephen Hemminger
2026-04-30  8:00   ` Bruce Richardson

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=20260429165845.2136843-39-bruce.richardson@intel.com \
    --to=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=techboard@dpdk.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