summaryrefslogtreecommitdiff
path: root/lib/netdev-afxdp.c
diff options
context:
space:
mode:
authorYi-Hung Wei <yihung.wei@gmail.com>2020-01-03 17:13:26 -0800
committerIlya Maximets <i.maximets@ovn.org>2020-01-18 02:11:39 +0100
commite8568993e062afcb75a7a54b1a615f04d7d6df37 (patch)
treed3b4ae4a9fb100baf9e97bd226d665a4781979d4 /lib/netdev-afxdp.c
parent105cf8df82f75d38b3afe1d7e1a4fe421f767ca2 (diff)
downloadopenvswitch-e8568993e062afcb75a7a54b1a615f04d7d6df37.tar.gz
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>
Diffstat (limited to 'lib/netdev-afxdp.c')
-rw-r--r--lib/netdev-afxdp.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c
index e96328a12..482400d8d 100644
--- a/lib/netdev-afxdp.c
+++ b/lib/netdev-afxdp.c
@@ -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;
}