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:
committed by
Ilya Maximets
parent
105cf8df82
commit
e8568993e0
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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
27
include/sparse/numa.h
Normal 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>
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user