[ovs-dev] [PATCH] netdev-afxdp: Fix transmission freeze in native mode without zerocopy.

Ilya Maximets i.maximets at ovn.org
Sun Jan 5 00:51:19 UTC 2020


Kernel uses 'xsk_generic_xmit()' for all modes where zerocopy is
not enabled:

   net/xdp/xsk.c
   433  static int __xsk_sendmsg(struct sock *sk)
   434  {
            ...
   442      return xs->zc ? xsk_zc_xmit(xs) : xsk_generic_xmit(sk);
   443  }

'xsk_generic_xmit ()' sends packets synchronously and no more than 16
packets at a time.  This means that we have to kick Tx with sendmsg()
for every 16 packets in simple native mode too, otherwise the packets
may never be sent.

Reported-by: William Tu <u9012063 at gmail.com>
Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2019-November/365076.html
Fixes: e8f5634484e8 ("netdev-afxdp: Best-effort configuration of XDP mode.")
Signed-off-by: Ilya Maximets <i.maximets at ovn.org>
---

This should fix the issue, however I didn't test the exact case.
So, testing is very welcome.

 lib/netdev-afxdp.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c
index 58365ed48..6ac0bc2dd 100644
--- a/lib/netdev-afxdp.c
+++ b/lib/netdev-afxdp.c
@@ -874,16 +874,17 @@ kick_tx(struct xsk_socket_info *xsk_info, enum afxdp_mode mode,
         return 0;
     }
 
-    /* In generic mode packet transmission is synchronous, and the kernel xmits
-     * only TX_BATCH_SIZE(16) packets for a single sendmsg syscall.
+    /* In all modes except native-with-zerocopy 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
      * all packets are transmitted. */
-    retries = (mode == OVS_AF_XDP_MODE_GENERIC)
+    retries = (mode != OVS_AF_XDP_MODE_NATIVE_ZC)
               ? xsk_info->outstanding_tx / KERNEL_TX_BATCH_SIZE
               : 0;
 kick_retry:
-    /* This causes system call into kernel's xsk_sendmsg, and
-     * xsk_generic_xmit (skb mode) or xsk_async_xmit (driver mode).
+    /* This causes system call into kernel's xsk_sendmsg, and xsk_generic_xmit
+     * (generic and native modes) or xsk_zc_xmit (native-with-zerocopy mode).
      */
     ret = sendto(xsk_socket__fd(xsk_info->xsk), NULL, 0, MSG_DONTWAIT,
                                 NULL, 0);
-- 
2.17.1



More information about the dev mailing list