diff options
author | Yi-Hung Wei <yihung.wei@gmail.com> | 2020-01-03 17:13:26 -0800 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2020-01-18 02:11:39 +0100 |
commit | e8568993e062afcb75a7a54b1a615f04d7d6df37 (patch) | |
tree | d3b4ae4a9fb100baf9e97bd226d665a4781979d4 /lib/netdev-afxdp.c | |
parent | 105cf8df82f75d38b3afe1d7e1a4fe421f767ca2 (diff) | |
download | openvswitch-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.c | 32 |
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; } |