mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +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
|
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::
|
set-up right::
|
||||||
|
|
||||||
ldd vswitchd/ovs-vswitchd
|
ldd vswitchd/ovs-vswitchd
|
||||||
|
@@ -286,6 +286,8 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
|
|||||||
AC_CHECK_FUNCS([pthread_spin_lock], [],
|
AC_CHECK_FUNCS([pthread_spin_lock], [],
|
||||||
[AC_MSG_ERROR([unable to find pthread_spin_lock for AF_XDP support])])
|
[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],
|
AC_DEFINE([HAVE_AF_XDP], [1],
|
||||||
[Define to 1 if AF_XDP support is available and enabled.])
|
[Define to 1 if AF_XDP support is available and enabled.])
|
||||||
LIBBPF_LDADD=" -lbpf -lelf"
|
LIBBPF_LDADD=" -lbpf -lelf"
|
||||||
|
@@ -5,6 +5,7 @@ noinst_HEADERS += \
|
|||||||
include/sparse/bits/floatn.h \
|
include/sparse/bits/floatn.h \
|
||||||
include/sparse/assert.h \
|
include/sparse/assert.h \
|
||||||
include/sparse/math.h \
|
include/sparse/math.h \
|
||||||
|
include/sparse/numa.h \
|
||||||
include/sparse/netinet/in.h \
|
include/sparse/netinet/in.h \
|
||||||
include/sparse/netinet/ip6.h \
|
include/sparse/netinet/ip6.h \
|
||||||
include/sparse/netpacket/packet.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/rtnetlink.h>
|
||||||
#include <linux/if_xdp.h>
|
#include <linux/if_xdp.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <numa.h>
|
||||||
|
#include <numaif.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@@ -42,6 +44,7 @@
|
|||||||
#include "openvswitch/list.h"
|
#include "openvswitch/list.h"
|
||||||
#include "openvswitch/thread.h"
|
#include "openvswitch/thread.h"
|
||||||
#include "openvswitch/vlog.h"
|
#include "openvswitch/vlog.h"
|
||||||
|
#include "ovs-numa.h"
|
||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -667,8 +670,27 @@ netdev_afxdp_reconfigure(struct netdev *netdev)
|
|||||||
{
|
{
|
||||||
struct netdev_linux *dev = netdev_linux_cast(netdev);
|
struct netdev_linux *dev = netdev_linux_cast(netdev);
|
||||||
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
|
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
|
||||||
|
struct bitmask *old_bm = NULL;
|
||||||
|
int old_policy, numa_id;
|
||||||
int err = 0;
|
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);
|
ovs_mutex_lock(&dev->mutex);
|
||||||
|
|
||||||
if (netdev->n_rxq == dev->requested_n_rxq
|
if (netdev->n_rxq == dev->requested_n_rxq
|
||||||
@@ -700,6 +722,16 @@ netdev_afxdp_reconfigure(struct netdev *netdev)
|
|||||||
netdev_change_seq_changed(netdev);
|
netdev_change_seq_changed(netdev);
|
||||||
out:
|
out:
|
||||||
ovs_mutex_unlock(&dev->mutex);
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user