2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

netdev-afxdp: NUMA-aware memory allocation for XSK related memory.

Currently, the AF_XDP socket (XSK) related memory are allocated by main
thread in the main thread's NUMA domain.  With the patch that detects
netdev-linux's NUMA node id, the PMD thread of AF_XDP port will be run on
the AF_XDP netdev's NUMA domain.  If the net device's NUMA domain
is different from the main thread's NUMA domain, we will have two
cross-NUMA memory accesses (netdev <-> memory, memory <-> CPU).

This patch addresses the aforementioned issue by allocating
the memory in the net device's NUMA domain.

Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Acked-by: William Tu <u9012063@gmail.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Yi-Hung Wei
2020-01-03 17:13:26 -08:00
committed by Ilya Maximets
parent 105cf8df82
commit e8568993e0
5 changed files with 63 additions and 1 deletions

View File

@@ -164,7 +164,7 @@ If a test case fails, check the log at::
Setup AF_XDP netdev
-------------------
Before running OVS with AF_XDP, make sure the libbpf and libelf are
Before running OVS with AF_XDP, make sure the libbpf, libelf, and libnuma are
set-up right::
ldd vswitchd/ovs-vswitchd

View File

@@ -286,6 +286,8 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
AC_CHECK_FUNCS([pthread_spin_lock], [],
[AC_MSG_ERROR([unable to find pthread_spin_lock for AF_XDP support])])
OVS_FIND_DEPENDENCY([numa_alloc_onnode], [numa], [libnuma])
AC_DEFINE([HAVE_AF_XDP], [1],
[Define to 1 if AF_XDP support is available and enabled.])
LIBBPF_LDADD=" -lbpf -lelf"

View File

@@ -5,6 +5,7 @@ noinst_HEADERS += \
include/sparse/bits/floatn.h \
include/sparse/assert.h \
include/sparse/math.h \
include/sparse/numa.h \
include/sparse/netinet/in.h \
include/sparse/netinet/ip6.h \
include/sparse/netpacket/packet.h \

27
include/sparse/numa.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2019 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CHECKER__
#error "Use this header only with sparse. It is not a correct implementation."
#endif
/* Avoid sparse warning: non-ANSI function declaration of function" */
#define numa_get_membind_compat() numa_get_membind_compat(void)
#define numa_get_interleave_mask_compat() numa_get_interleave_mask_compat(void)
#define numa_get_run_node_mask_compat() numa_get_run_node_mask_compat(void)
/* Get actual <numa.h> definitions for us to annotate and build on. */
#include_next<numa.h>

View File

@@ -26,6 +26,8 @@
#include <linux/rtnetlink.h>
#include <linux/if_xdp.h>
#include <net/if.h>
#include <numa.h>
#include <numaif.h>
#include <poll.h>
#include <stdlib.h>
#include <sys/resource.h>
@@ -42,6 +44,7 @@
#include "openvswitch/list.h"
#include "openvswitch/thread.h"
#include "openvswitch/vlog.h"
#include "ovs-numa.h"
#include "packets.h"
#include "socket-util.h"
#include "util.h"
@@ -667,8 +670,27 @@ netdev_afxdp_reconfigure(struct netdev *netdev)
{
struct netdev_linux *dev = netdev_linux_cast(netdev);
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
struct bitmask *old_bm = NULL;
int old_policy, numa_id;
int err = 0;
/* Allocate all the xsk related memory in the netdev's NUMA domain. */
if (numa_available() != -1 && ovs_numa_get_n_numas() > 1) {
numa_id = netdev_get_numa_id(netdev);
if (numa_id != NETDEV_NUMA_UNSPEC) {
old_bm = numa_allocate_nodemask();
if (get_mempolicy(&old_policy, old_bm->maskp, old_bm->size + 1,
NULL, 0)) {
VLOG_INFO("Failed to get NUMA memory policy: %s.",
ovs_strerror(errno));
numa_bitmask_free(old_bm);
old_bm = NULL;
} else {
numa_set_preferred(numa_id);
}
}
}
ovs_mutex_lock(&dev->mutex);
if (netdev->n_rxq == dev->requested_n_rxq
@@ -700,6 +722,16 @@ netdev_afxdp_reconfigure(struct netdev *netdev)
netdev_change_seq_changed(netdev);
out:
ovs_mutex_unlock(&dev->mutex);
if (old_bm) {
if (set_mempolicy(old_policy, old_bm->maskp, old_bm->size + 1)) {
VLOG_WARN("Failed to restore NUMA memory policy: %s.",
ovs_strerror(errno));
/* Can't restore correctly. Try to use localalloc as the most
* likely default memory policy. */
numa_set_localalloc();
}
numa_bitmask_free(old_bm);
}
return err;
}