aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2021-12-02 16:06:12 +0100
committerAndrew Yourtchenko <ayourtch@gmail.com>2023-06-08 11:53:21 +0000
commitf40bdbb80d59be824ee9cc9273785f9548a3fe77 (patch)
tree9e89d3615f62ef9187e9f3be211e5209ec5eee19
parentf441b5d0ed8ff9d87412c1640dfec93e9cba03bd (diff)
af_xdp: make sure all packets are transmitted
AF_XDP socket will only tx enqueued packets up to a max batch size so we need to retry until everything has been sent. Type: fix Change-Id: Ia487ab63d3e85a478471cd1d679c5fb471804ba3 Signed-off-by: Benoît Ganne <bganne@cisco.com>
-rw-r--r--src/plugins/af_xdp/input.c4
-rw-r--r--src/plugins/af_xdp/output.c15
2 files changed, 12 insertions, 7 deletions
diff --git a/src/plugins/af_xdp/input.c b/src/plugins/af_xdp/input.c
index 4f3ac5725a4..08b503b1641 100644
--- a/src/plugins/af_xdp/input.c
+++ b/src/plugins/af_xdp/input.c
@@ -15,7 +15,6 @@
*------------------------------------------------------------------
*/
-#include <poll.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vlib/pci/pci.h>
@@ -89,8 +88,7 @@ af_xdp_device_input_refill_db (vlib_main_t * vm,
if (clib_spinlock_trylock_if_init (&rxq->syscall_lock))
{
- struct pollfd fd = { .fd = rxq->xsk_fd, .events = POLLIN | POLLOUT };
- int ret = poll (&fd, 1, 0);
+ int ret = recvmsg (rxq->xsk_fd, 0, MSG_DONTWAIT);
clib_spinlock_unlock_if_init (&rxq->syscall_lock);
if (PREDICT_FALSE (ret < 0))
{
diff --git a/src/plugins/af_xdp/output.c b/src/plugins/af_xdp/output.c
index d1500a63cbb..8136d918a75 100644
--- a/src/plugins/af_xdp/output.c
+++ b/src/plugins/af_xdp/output.c
@@ -1,4 +1,3 @@
-#include <poll.h>
#include <string.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
@@ -101,11 +100,19 @@ af_xdp_device_output_tx_db (vlib_main_t * vm,
if (xsk_ring_prod__needs_wakeup (&txq->tx))
{
- struct pollfd fd = { .fd = txq->xsk_fd, .events = POLLIN | POLLOUT };
- int ret = poll (&fd, 1, 0);
+ const struct msghdr msg = {};
+ int ret;
+ /* On tx, xsk socket will only tx up to TX_BATCH_SIZE, as defined in
+ * kernel net/xdp/xsk.c. Unfortunately we do not know how much this is,
+ * our only option is to retry until everything is sent... */
+ do
+ {
+ ret = sendmsg (txq->xsk_fd, &msg, MSG_DONTWAIT);
+ }
+ while (ret < 0 && EAGAIN == errno);
if (PREDICT_FALSE (ret < 0))
{
- /* something bad is happening */
+ /* not EAGAIN: something bad is happening */
vlib_error_count (vm, node->node_index,
AF_XDP_TX_ERROR_SYSCALL_FAILURES, 1);
af_xdp_device_error (ad, "tx poll() failed");