2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 15:25:22 +00:00

ovs-numa: Support non-contiguous numa nodes and offline CPU cores.

This change removes the assumption that numa nodes and cores are numbered
contiguously in linux.  This change is required to support some Power
systems.

A check has been added to verify that cores are online,
offline cores result in non-contiguously numbered cores.

DPDK EAL option generation is updated to work with non-contiguous numa nodes.
These options can be seen in the ovs-vswitchd.log.  For example:
a system containing only numa nodes 0 and 8 will generate the following:

EAL ARGS: ovs-vswitchd --socket-mem 1024,0,0,0,0,0,0,0,1024 \
                       --socket-limit 1024,0,0,0,0,0,0,0,1024 -l 0

Tests for pmd and dpif-netdev have been updated to validate non-contiguous
numbered nodes.

Signed-off-by: David Wilder <dwilder@us.ibm.com>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
David Wilder
2021-06-22 11:53:08 -07:00
committed by Ilya Maximets
parent 154983c592
commit 3da3cc1a0c
6 changed files with 144 additions and 32 deletions

View File

@@ -130,22 +130,63 @@ construct_dpdk_options(const struct smap *ovs_other_config, struct svec *args)
}
}
static int
compare_numa_node_list(const void *a_, const void *b_)
{
int a = *(const int *) a_;
int b = *(const int *) b_;
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
static char *
construct_dpdk_socket_mem(void)
{
const char *def_value = "1024";
int numa, numa_nodes = ovs_numa_get_n_numas();
struct ds dpdk_socket_mem = DS_EMPTY_INITIALIZER;
if (numa_nodes == 0 || numa_nodes == OVS_NUMA_UNSPEC) {
numa_nodes = 1;
}
/* Build a list of all numa nodes with at least one core. */
struct ovs_numa_dump *dump = ovs_numa_dump_n_cores_per_numa(1);
size_t n_numa_nodes = hmap_count(&dump->numas);
int *numa_node_list = xcalloc(n_numa_nodes, sizeof *numa_node_list);
ds_put_cstr(&dpdk_socket_mem, def_value);
for (numa = 1; numa < numa_nodes; ++numa) {
ds_put_format(&dpdk_socket_mem, ",%s", def_value);
}
const struct ovs_numa_info_numa *node;
int k = 0, last_node = 0;
FOR_EACH_NUMA_ON_DUMP(node, dump) {
if (k >= n_numa_nodes) {
break;
}
numa_node_list[k++] = node->numa_id;
}
qsort(numa_node_list, k, sizeof *numa_node_list, compare_numa_node_list);
for (int i = 0; i < n_numa_nodes; i++) {
while (numa_node_list[i] > last_node &&
numa_node_list[i] != OVS_NUMA_UNSPEC &&
numa_node_list[i] <= MAX_NUMA_NODES) {
if (last_node == 0) {
ds_put_format(&dpdk_socket_mem, "%s", "0");
} else {
ds_put_format(&dpdk_socket_mem, ",%s", "0");
}
last_node++;
}
if (numa_node_list[i] == 0) {
ds_put_format(&dpdk_socket_mem, "%s", def_value);
} else {
ds_put_format(&dpdk_socket_mem, ",%s", def_value);
}
last_node++;
}
free(numa_node_list);
ovs_numa_dump_destroy(dump);
return ds_cstr(&dpdk_socket_mem);
}