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>
This commit is contained in:

committed by
Andrew Yourtchenko

parent
f441b5d0ed
commit
f40bdbb80d
@ -15,7 +15,6 @@
|
|||||||
*------------------------------------------------------------------
|
*------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <poll.h>
|
|
||||||
#include <vlib/vlib.h>
|
#include <vlib/vlib.h>
|
||||||
#include <vlib/unix/unix.h>
|
#include <vlib/unix/unix.h>
|
||||||
#include <vlib/pci/pci.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))
|
if (clib_spinlock_trylock_if_init (&rxq->syscall_lock))
|
||||||
{
|
{
|
||||||
struct pollfd fd = { .fd = rxq->xsk_fd, .events = POLLIN | POLLOUT };
|
int ret = recvmsg (rxq->xsk_fd, 0, MSG_DONTWAIT);
|
||||||
int ret = poll (&fd, 1, 0);
|
|
||||||
clib_spinlock_unlock_if_init (&rxq->syscall_lock);
|
clib_spinlock_unlock_if_init (&rxq->syscall_lock);
|
||||||
if (PREDICT_FALSE (ret < 0))
|
if (PREDICT_FALSE (ret < 0))
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include <poll.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vlib/vlib.h>
|
#include <vlib/vlib.h>
|
||||||
#include <vlib/unix/unix.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))
|
if (xsk_ring_prod__needs_wakeup (&txq->tx))
|
||||||
{
|
{
|
||||||
struct pollfd fd = { .fd = txq->xsk_fd, .events = POLLIN | POLLOUT };
|
const struct msghdr msg = {};
|
||||||
int ret = poll (&fd, 1, 0);
|
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))
|
if (PREDICT_FALSE (ret < 0))
|
||||||
{
|
{
|
||||||
/* something bad is happening */
|
/* not EAGAIN: something bad is happening */
|
||||||
vlib_error_count (vm, node->node_index,
|
vlib_error_count (vm, node->node_index,
|
||||||
AF_XDP_TX_ERROR_SYSCALL_FAILURES, 1);
|
AF_XDP_TX_ERROR_SYSCALL_FAILURES, 1);
|
||||||
af_xdp_device_error (ad, "tx poll() failed");
|
af_xdp_device_error (ad, "tx poll() failed");
|
||||||
|
Reference in New Issue
Block a user