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
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"
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 \
--- /dev/null
+/*
+ * 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>
#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>
#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"
{
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
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;
}