]> git.proxmox.com Git - mirror_ovs.git/commitdiff
netdev-afxdp: NUMA-aware memory allocation for XSK related memory.
authorYi-Hung Wei <yihung.wei@gmail.com>
Sat, 4 Jan 2020 01:13:26 +0000 (17:13 -0800)
committerIlya Maximets <i.maximets@ovn.org>
Sat, 18 Jan 2020 01:11:39 +0000 (02:11 +0100)
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>
Documentation/intro/install/afxdp.rst
acinclude.m4
include/sparse/automake.mk
include/sparse/numa.h [new file with mode: 0644]
lib/netdev-afxdp.c

index 7b0736c9611444c98977d8e4c9dd48d93b4c02e2..c4685fa7ebacaa8ea4179226036b19f475613d41 100644 (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
index 1c8791d53488064863c548d81a5d51d7dc2c439f..c1470ccc6bc4eb74fb2517d06ae49145a97144d5 100644 (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"
index 073631e8c0824befb551f735cd6d0568f18576fd..974ad3fe55f7fff498be15b60d797f1754a330fa 100644 (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 \
diff --git a/include/sparse/numa.h b/include/sparse/numa.h
new file mode 100644 (file)
index 0000000..3691a0e
--- /dev/null
@@ -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>
index e96328a121012e71a0afe4ac6e0aaaf17a7bd183..482400d8d13599aa6dec4b68514df4bc484fbe49 100644 (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;
 }