OVS currently uses other_config:dpdk-lcore-mask <coremask> directly
in DPDK rte_eal_init() with '-c <coremask>' argument.
'-c' argument is now deprecated from DPDK and will be removed in
DPDK 25.11, so OVS will no longer be able to use the '-c <coremask>'
argument.
Convert dpdk-lcore-mask core mask to a core list that can be used with
'--lcores' and add some tests.
Using the '--lcores' argument also adds compability for using a core
in the core mask that is greater than the max lcore, similar to commit
fe53b478f86e ("dpdk: Fix main lcore on systems with many cores.")
Signed-off-by: Kevin Traynor <[email protected]>
---
lib/dpdk.c | 76 +++++++++++++++++++++++++++++++++++--
tests/pmd.at | 15 --------
tests/system-dpdk-macros.at | 15 ++++++++
tests/system-dpdk.at | 73 +++++++++++++++++++++++++++++++++++
tests/testsuite.at | 1 +
5 files changed, 161 insertions(+), 19 deletions(-)
diff --git a/lib/dpdk.c b/lib/dpdk.c
index 1f4f2bf08..a3e397f3c 100644
--- a/lib/dpdk.c
+++ b/lib/dpdk.c
@@ -65,4 +65,58 @@ args_contains(const struct svec *args, const char *value)
}
+#define LCORE_MAX_STR_SIZE 23 /* Max size of single lcore assignment. */
+#define LCORE_MAX_ARGS_LENGTH 256 /* Max size of DPDK lcores list. */
+
+/* Converts a hexadecimal core mask to DPDK lcore list format. */
+static char *
+cmask_to_lcore_list(const char *cmask)
+{
+ char cvalue[LCORE_MAX_STR_SIZE] = "";
+ char *lcores = NULL;
+ int num_lcores = 0;
+ int core_id = 0;
+ int end_idx = 0;
+
+ /* Ignore leading 0x. */
+ if (!strncmp(cmask, "0x", 2) || !strncmp(cmask, "0X", 2)) {
+ end_idx = 2;
+ }
+
+ for (int i = strlen(cmask) - 1; i >= end_idx; i--) {
+ char hex = cmask[i];
+ int bin;
+
+ bin = hexit_value(hex);
+ if (bin == -1) {
+ VLOG_WARN("Invalid lcore mask: %c", cmask[i]);
+ bin = 0;
+ }
+ for (int j = 0; j < 4; j++) {
+ if ((bin >> j) & 0x1) {
+ if (!num_lcores) {
+ lcores = xmalloc(LCORE_MAX_STR_SIZE);
+ lcores[0] = '\0';
+ snprintf(cvalue, LCORE_MAX_STR_SIZE, "0@%d", core_id);
+ num_lcores++;
+ } else {
+ int new_size = strlen(lcores) + LCORE_MAX_STR_SIZE;
+
+ if (new_size > LCORE_MAX_ARGS_LENGTH) {
+ VLOG_INFO("Concatenating DPDK lcore list from"
+ " dpdk-lcore-mask as string too long.");
+ return lcores;
+ }
+ lcores = xrealloc(lcores, new_size);
+ snprintf(cvalue, LCORE_MAX_STR_SIZE, ",%d@%d",
+ num_lcores++, core_id);
+ }
+ strncat(lcores, cvalue, LCORE_MAX_STR_SIZE);
+ }
+ core_id++;
+ }
+ }
+ return lcores;
+}
+
static void
construct_dpdk_options(const struct smap *ovs_other_config, struct svec *args)
@@ -71,10 +125,11 @@ construct_dpdk_options(const struct smap
*ovs_other_config, struct svec *args)
const char *ovs_configuration;
const char *dpdk_option;
+ char *(*param_conversion) (const char *);
bool default_enabled;
const char *default_value;
} opts[] = {
- {"dpdk-lcore-mask", "-c", false, NULL},
- {"dpdk-hugepage-dir", "--huge-dir", false, NULL},
- {"dpdk-socket-limit", "--socket-limit", false, NULL},
+ {"dpdk-lcore-mask", "--lcores", cmask_to_lcore_list, false, NULL},
+ {"dpdk-hugepage-dir", "--huge-dir", NULL, false, NULL},
+ {"dpdk-socket-limit", "--socket-limit", NULL, false, NULL},
};
@@ -91,9 +146,22 @@ construct_dpdk_options(const struct smap *ovs_other_config,
struct svec *args)
if (value) {
if (!args_contains(args, opts[i].dpdk_option)) {
+ char *dpdk_val = NULL;
+
+ if (opts[i].param_conversion) {
+ dpdk_val = (opts[i].param_conversion)(value);
+ if (!dpdk_val) {
+ VLOG_WARN("Ignoring database defined option '%s'"
+ " due to invalid value '%s'",
+ opts[i].ovs_configuration, value);
+ continue;
+ }
+ value = dpdk_val;
+ }
svec_add(args, opts[i].dpdk_option);
svec_add(args, value);
+ free(dpdk_val);
} else {
VLOG_WARN("Ignoring database defined option '%s' due to "
- "dpdk-extra config", opts[i].dpdk_option);
+ "dpdk-extra config", opts[i].ovs_configuration);
}
}
diff --git a/tests/pmd.at b/tests/pmd.at
index 35a44b4df..8254ac3b0 100644
--- a/tests/pmd.at
+++ b/tests/pmd.at
@@ -27,19 +27,4 @@ flow_dump_prepend_pmd () {
m4_divert_pop([PREPARE_TESTS])
-dnl CHECK_CPU_DISCOVERED([n_cpu])
-dnl
-dnl Waits until CPUs discovered and checks if number of discovered CPUs
-dnl is greater or equal to 'n_cpu'. Without parameters checks that at
-dnl least one CPU discovered.
-m4_define([CHECK_CPU_DISCOVERED], [
- PATTERN="Discovered [[0-9]]* NUMA nodes and [[0-9]]* CPU cores"
- OVS_WAIT_UNTIL([grep "$PATTERN" ovs-vswitchd.log])
- N_CPU=$(grep "$PATTERN" ovs-vswitchd.log | sed -e 's/.* \([[0-9]]*\) CPU
cores/\1/')
- if [[ -z "$1" ]]
- then AT_CHECK([test "$N_CPU" -gt "0"])
- else AT_SKIP_IF([test "$N_CPU" -lt "$1"])
- fi
-])
-
dnl CHECK_PMD_THREADS_CREATED([n_threads], [numa_id], [+line])
dnl
diff --git a/tests/system-dpdk-macros.at b/tests/system-dpdk-macros.at
index f8ba76673..aae49d90f 100644
--- a/tests/system-dpdk-macros.at
+++ b/tests/system-dpdk-macros.at
@@ -200,2 +200,17 @@ m4_define([CONFIGURE_VETH_OFFLOADS],
AT_CHECK([ethtool -K $1 txvlan off], [0], [ignore], [ignore])]
)
+
+dnl CHECK_CPU_DISCOVERED([n_cpu])
+dnl
+dnl Waits until CPUs discovered and checks if number of discovered CPUs
+dnl is greater or equal to 'n_cpu'. Without parameters checks that at
+dnl least one CPU discovered.
+m4_define([CHECK_CPU_DISCOVERED], [
+ PATTERN="Discovered [[0-9]]* NUMA nodes and [[0-9]]* CPU cores"
+ OVS_WAIT_UNTIL([grep "$PATTERN" ovs-vswitchd.log])
+ N_CPU=$(grep "$PATTERN" ovs-vswitchd.log | sed -e 's/.* \([[0-9]]*\) CPU
cores/\1/')
+ if [[ -z "$1" ]]
+ then AT_CHECK([test "$N_CPU" -gt "0"])
+ else AT_SKIP_IF([test "$N_CPU" -lt "$1"])
+ fi
+])
\ No newline at end of file
diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at
index e79c75565..afbf84f59 100644
--- a/tests/system-dpdk.at
+++ b/tests/system-dpdk.at
@@ -52,7 +52,80 @@ AT_CLEANUP
dnl --------------------------------------------------------------------------
+dnl Check dpdk-lcore-mask conversion for only first bit
+AT_SETUP([OVS-DPDK - dpdk-lcore-mask conversion - single])
+AT_KEYWORDS([dpdk])
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START_OVSDB()
+OVS_DPDK_START_VSWITCHD([--no-pci])
+CHECK_CPU_DISCOVERED()
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch .
other_config:dpdk-lcore-mask=0x1])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
+expected_lcores="lcores 0@0"
+OVS_WAIT_UNTIL([grep "$expected_lcores" ovs-vswitchd.log])
+OVS_DPDK_STOP_VSWITCHD
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
+dnl Check dpdk-lcore-mask conversion for only multiple bits
+AT_SETUP([OVS-DPDK - dpdk-lcore-mask conversion - multi])
+AT_KEYWORDS([dpdk])
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START_OVSDB()
+OVS_DPDK_START_VSWITCHD([--no-pci])
+CHECK_CPU_DISCOVERED(4)
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch .
other_config:dpdk-lcore-mask=0xf])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
+expected_lcores="lcores 0@0,1@1,2@2,3@3"
+OVS_WAIT_UNTIL([grep "$expected_lcores" ovs-vswitchd.log])
+OVS_DPDK_STOP_VSWITCHD
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+dnl Check dpdk-lcore-mask conversion for max length string
+AT_SETUP([OVS-DPDK - dpdk-lcore-mask conversion - max])
+AT_KEYWORDS([dpdk])
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START_OVSDB()
+OVS_DPDK_START_VSWITCHD([--no-pci])
+CHECK_CPU_DISCOVERED(42)
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch .
other_config:dpdk-lcore-mask=0x7ffffffffff])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
+expected_lcores="lcores
0@0,1@1,2@2,3@3,4@4,5@5,6@6,7@7,8@8,9@9,10@10,11@11,12@12,13@13,14@14,15@15,16@16,17@17,18@18,19@19,20@20,21@21,22@22,23@23,24@24,25@25,26@26,27@27,28@28,29@29,30@30,31@31,32@32,33@33,34@34,35@35,36@36,37@37,38@38,39@39,40@40,41@41,42@42"
+OVS_WAIT_UNTIL([grep "$expected_lcores" ovs-vswitchd.log])
+OVS_DPDK_STOP_VSWITCHD
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+dnl Check dpdk-lcore-mask conversion for > max length string
+AT_SETUP([OVS-DPDK - dpdk-lcore-mask conversion - cat])
+AT_KEYWORDS([dpdk])
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START_OVSDB()
+OVS_DPDK_START_VSWITCHD([--no-pci])
+CHECK_CPU_DISCOVERED(42)
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch .
other_config:dpdk-lcore-mask=0xfffffffffff])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
+OVS_WAIT_UNTIL([grep "Concatenating DPDK lcore list from dpdk-lcore-mask as
string too long." ovs-vswitchd.log])
+expected_lcores="lcores
0@0,1@1,2@2,3@3,4@4,5@5,6@6,7@7,8@8,9@9,10@10,11@11,12@12,13@13,14@14,15@15,16@16,17@17,18@18,19@19,20@20,21@21,22@22,23@23,24@24,25@25,26@26,27@27,28@28,29@29,30@30,31@31,32@32,33@33,34@34,35@35,36@36,37@37,38@38,39@39,40@40,41@41,42@42"
+OVS_WAIT_UNTIL([grep "$expected_lcores" ovs-vswitchd.log])
+OVS_DPDK_STOP_VSWITCHD
+AT_CLEANUP
dnl --------------------------------------------------------------------------
+
+dnl Check dpdk-lcore-mask conversion for zero
+AT_SETUP([OVS-DPDK - dpdk-lcore-mask conversion - zeromask])
+AT_KEYWORDS([dpdk])
+OVS_DPDK_PRE_CHECK()
+OVS_DPDK_START_OVSDB()
+OVS_DPDK_START_VSWITCHD([--no-pci])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch .
other_config:dpdk-lcore-mask=0x0])
+AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
+OVS_WAIT_UNTIL([grep "Ignoring database defined option 'dpdk-lcore-mask' due
to invalid value '0x0'" ovs-vswitchd.log])
+expected_lcores="lcores 0@0"
+OVS_WAIT_UNTIL([grep "$expected_lcores" ovs-vswitchd.log])
+OVS_DPDK_STOP_VSWITCHD(["/Ignoring database defined option/d"])
+AT_CLEANUP
+dnl --------------------------------------------------------------------------
+
dnl Add standard DPDK PHY port
AT_SETUP([OVS-DPDK - add standard DPDK port])
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 9d77a9f51..51e12583b 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -20,4 +20,5 @@ m4_include([tests/ovs-macros.at])
m4_include([tests/ovsdb-macros.at])
m4_include([tests/ofproto-macros.at])
+m4_include([tests/system-dpdk-macros.at])
m4_include([tests/completion.at])
--
2.51.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev