Skip to content

Commit

Permalink
netdev-afxdp: NUMA-aware memory allocation for XSK related memory.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: William Tu <[email protected]>
Signed-off-by: Ilya Maximets <[email protected]>
  • Loading branch information
YiHungWei authored and igsilya committed Jan 18, 2020
1 parent 105cf8d commit e856899
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Documentation/intro/install/afxdp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions include/sparse/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
27 changes: 27 additions & 0 deletions include/sparse/numa.h
Original file line number Diff line number Diff line change
@@ -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>
32 changes: 32 additions & 0 deletions lib/netdev-afxdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit e856899

Please sign in to comment.