On 27 Aug 2019, at 1:02, William Tu wrote:
The patch adds support for using need_wakeup flag in AF_XDP rings.
When this flag is used, it means that OVS has to explicitly wake
up the kernel RX, using poll() syscall and wake up TX, using sendto()
syscall. This feature improves the performance by avoiding unnecessary
syscalls, so keeping more CPU time in userspace to process packets.
On Intel Xeon E5-2620 v3 2.4GHz system, performance of physical port
to physical port improves from 6.1Mpps to 7.3Mpps.
Did some more testing and with PVP I see a performance decrease, with
physical to physical I see an increase.
Tests are performed with a port redirect open flow rule on an ixgbe
(Xeon E5-2690 v4 2.60GHz):
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
| PVP | Number of flows | 64 | 128 | 256 | 512 |
768 | 1024 | 1514 |
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
| master | 1000 | 737896 | 700643 | 682915 | 648386 |
621792 | 582821 | 527899 |
| Patch | 1000 | 734179 | 696515 | 676712 | 646536 |
619600 | 578546 | 519965 |
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
| Port2Port | Number of flows | 64 | 128 | 256 | 512 |
768 | 1024 | 1514 |
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
| master | 1000 | 3351114 | 3236581 | 3143710 | 2349598 |
1586276 | 1197304 | 814854 |
| Patch | 1000 | 3571733 | 3488697 | 3448908 | 2349593 |
1586276 | 1197304 | 814854 |
+-----------+-----------------+---------+---------+---------+---------+---------+---------+--------+
Did not research why PVP is slower, maybe related to the TAP interface
with AF_XDP?
See one small comment inline…
Suggested-by: Eelco Chaudron <[email protected]>
Signed-off-by: William Tu <[email protected]>
---
acinclude.m4 | 5 +++++
lib/netdev-afxdp.c | 51
+++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/acinclude.m4 b/acinclude.m4
index 116ffcf9096d..8821b821ec3c 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -276,6 +276,11 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
[Define to 1 if AF_XDP support is available and
enabled.])
LIBBPF_LDADD=" -lbpf -lelf"
AC_SUBST([LIBBPF_LDADD])
+
+ AC_CHECK_DECL([xsk_ring_prod__needs_wakeup], [
+ AC_DEFINE([HAVE_XDP_NEED_WAKEUP], [1],
+ [XDP need wakeup support detected in xsk.h.])
+ ], [], [#include <bpf/xsk.h>])
fi
AM_CONDITIONAL([HAVE_AF_XDP], test "$AF_XDP_ENABLE" = true)
])
diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c
index e5b058d08a09..d14d100e8fa3 100644
--- a/lib/netdev-afxdp.c
+++ b/lib/netdev-afxdp.c
@@ -26,6 +26,7 @@
#include <linux/rtnetlink.h>
#include <linux/if_xdp.h>
#include <net/if.h>
+#include <poll.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/socket.h>
@@ -117,6 +118,48 @@ struct xsk_socket_info {
atomic_uint64_t tx_dropped;
};
+#ifdef HAVE_XDP_NEED_WAKEUP
+static inline void
+xsk_rx_need_wakeup(struct xsk_umem_info *umem,
+ struct netdev *netdev, int fd) {
+ struct pollfd pfd;
+ int ret;
+
+ if (xsk_ring_prod__needs_wakeup(&umem->fq)) {
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ ret = poll(&pfd, 1, 1000);
Think we should call the poll with a 0 delay as the kernel should have
something waiting. If for some reason it doesn’t we should not wait
for a second.
I ran the patch with a 0 timeout, and see no performance differences, or
any of the below warning messages.
+ if (OVS_UNLIKELY(ret == 0)) {
+ VLOG_WARN_RL(&rl, "%s: poll rx fd timeout.",
+ netdev_get_name(netdev));
+ } else if (OVS_UNLIKELY(ret < 0)) {
+ VLOG_WARN_RL(&rl, "%s: error polling rx fd: %s.",
+ netdev_get_name(netdev),
+ ovs_strerror(ret));
+ }
+ }
+}
+
+static inline bool
+xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info)
+{
+ return xsk_ring_prod__needs_wakeup(&xsk_info->tx);
+}
+#else
+static inline void
+xsk_rx_need_wakeup(struct xsk_umem_info *umem OVS_UNUSED,
+ struct netdev *netdev OVS_UNUSED, int fd
OVS_UNUSED) {
+ /* Nothing. */
+}
+
+static inline bool
+xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info OVS_UNUSED)
+{
+ return true;
+}
+#endif /* HAVE_XDP_NEED_WAKEUP */
+
static void
netdev_afxdp_cleanup_unused_pool(struct unused_pool *pool)
{
@@ -257,6 +300,10 @@ xsk_configure_socket(struct xsk_umem_info *umem,
uint32_t ifindex,
cfg.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST |
XDP_FLAGS_SKB_MODE;
}
+#ifdef HAVE_XDP_NEED_WAKEUP
+ cfg.bind_flags |= XDP_USE_NEED_WAKEUP;
+#endif
+
if (if_indextoname(ifindex, devname) == NULL) {
VLOG_ERR("ifindex %d to devname failed (%s)",
ifindex, ovs_strerror(errno));
@@ -660,6 +707,7 @@ netdev_afxdp_rxq_recv(struct netdev_rxq *rxq_,
struct dp_packet_batch *batch,
rcvd = xsk_ring_cons__peek(&xsk_info->rx, BATCH_SIZE, &idx_rx);
if (!rcvd) {
+ xsk_rx_need_wakeup(umem, netdev, rx->fd);
return EAGAIN;
}
@@ -709,6 +757,9 @@ kick_tx(struct xsk_socket_info *xsk_info, int
xdpmode)
int ret, retries;
static const int KERNEL_TX_BATCH_SIZE = 16;
+ if (!xsk_tx_need_wakeup(xsk_info)) {
+ return 0;
+ }
/* In SKB_MODE packet transmission is synchronous, and the kernel
xmits
* only TX_BATCH_SIZE(16) packets for a single sendmsg syscall.
* So, we have to kick the kernel (n_packets / 16) times to be
sure that
--
2.7.4
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev