2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-30 22:05:19 +00:00

dpdk: Support running PMD threads on any core.

Previously in OVS, a PMD thread running on cpu X used lcore X.
This assumption limited OVS to run PMD threads on physical cpu <
RTE_MAX_LCORE.

DPDK 20.08 introduced a new API that associates a non-EAL thread to a free
lcore. This new API does not change the thread characteristics (like CPU
affinity) and let OVS run its PMD threads on any cpu regardless of
RTE_MAX_LCORE.

The DPDK multiprocess feature is not compatible with this new API and is
disabled.

DPDK still limits the number of lcores to RTE_MAX_LCORE (128 on x86_64)
which should be enough for OVS pmd threads (hopefully).

DPDK lcore/OVS pmd threads mapping are logged at threads when trying to
attach a OVS PMD thread, and when detaching.
A new command is added to help get DPDK point of view of the DPDK lcores
at any time:

$ ovs-appctl dpdk/lcore-list
lcore 0, socket 0, role RTE, cpuset 0
lcore 1, socket 0, role NON_EAL, cpuset 1
lcore 2, socket 0, role NON_EAL, cpuset 15

Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
David Marchand
2021-11-10 17:53:41 +01:00
committed by Ilya Maximets
parent 356f362068
commit b84386fa9a
7 changed files with 72 additions and 13 deletions

View File

@@ -35,6 +35,7 @@
#include "netdev-offload-provider.h"
#include "openvswitch/dynamic-string.h"
#include "openvswitch/vlog.h"
#include "ovs-atomic.h"
#include "ovs-numa.h"
#include "smap.h"
#include "svec.h"
@@ -50,10 +51,11 @@ static char *vhost_sock_dir = NULL; /* Location of vhost-user sockets */
static bool vhost_iommu_enabled = false; /* Status of vHost IOMMU support */
static bool vhost_postcopy_enabled = false; /* Status of vHost POSTCOPY
* support. */
static bool dpdk_initialized = false; /* Indicates successful initialization
* of DPDK. */
static bool per_port_memory = false; /* Status of per port memory support */
/* Indicates successful initialization of DPDK. */
static atomic_bool dpdk_initialized = ATOMIC_VAR_INIT(false);
static int
process_vhost_flags(char *flag, const char *default_val, int size,
const struct smap *ovs_other_config,
@@ -477,6 +479,12 @@ dpdk_init__(const struct smap *ovs_other_config)
return false;
}
if (!rte_mp_disable()) {
VLOG_EMER("Could not disable multiprocess, DPDK won't be available.");
rte_eal_cleanup();
return false;
}
if (VLOG_IS_DBG_ENABLED()) {
size_t size;
char *response = NULL;
@@ -496,6 +504,8 @@ dpdk_init__(const struct smap *ovs_other_config)
}
}
unixctl_command_register("dpdk/lcore-list", "", 0, 0,
dpdk_unixctl_mem_stream, rte_lcore_dump);
unixctl_command_register("dpdk/log-list", "", 0, 0,
dpdk_unixctl_mem_stream, rte_log_dump);
unixctl_command_register("dpdk/log-set", "{level | pattern:level}", 0,
@@ -545,7 +555,7 @@ dpdk_init(const struct smap *ovs_other_config)
} else {
VLOG_INFO_ONCE("DPDK Disabled - Use other_config:dpdk-init to enable");
}
dpdk_initialized = enabled;
atomic_store_relaxed(&dpdk_initialized, enabled);
}
const char *
@@ -575,15 +585,40 @@ dpdk_per_port_memory(void)
bool
dpdk_available(void)
{
return dpdk_initialized;
bool initialized;
atomic_read_relaxed(&dpdk_initialized, &initialized);
return initialized;
}
void
dpdk_set_lcore_id(unsigned cpu)
bool
dpdk_attach_thread(unsigned cpu)
{
/* NON_PMD_CORE_ID is reserved for use by non pmd threads. */
ovs_assert(cpu != NON_PMD_CORE_ID);
RTE_PER_LCORE(_lcore_id) = cpu;
if (!dpdk_available()) {
return false;
}
if (rte_thread_register() < 0) {
VLOG_WARN("DPDK max threads count has been reached. "
"PMD thread performance may be impacted.");
return false;
}
VLOG_INFO("PMD thread uses DPDK lcore %u.", rte_lcore_id());
return true;
}
void
dpdk_detach_thread(void)
{
unsigned int lcore_id;
lcore_id = rte_lcore_id();
rte_thread_unregister();
VLOG_INFO("PMD thread released DPDK lcore %u.", lcore_id);
}
void
@@ -596,7 +631,7 @@ void
dpdk_status(const struct ovsrec_open_vswitch *cfg)
{
if (cfg) {
ovsrec_open_vswitch_set_dpdk_initialized(cfg, dpdk_initialized);
ovsrec_open_vswitch_set_dpdk_initialized(cfg, dpdk_available());
ovsrec_open_vswitch_set_dpdk_version(cfg, rte_version());
}
}