diff options
author | Mohammed Hawari <mohammed@hawari.fr> | 2022-02-24 15:19:01 +0100 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2022-08-08 14:36:32 +0000 |
commit | 8a419d5b5dd3da5d3d8597cd65ac74f191fb7da7 (patch) | |
tree | 5116dd8178f594873226dfdf5b1788185af4e334 /src/vnet/devices/af_packet/device.c | |
parent | ce91af8ad27e5ddef1e1f8316129bfcaa3de9ef6 (diff) |
devices: af_packet, fix tx stall by retrying failed sendto
Change-Id: I6bed66f740b34673a4883eda1c7f7310c57e131b
Type: fix
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vnet/devices/af_packet/device.c')
-rw-r--r-- | src/vnet/devices/af_packet/device.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c index 1e177f625b2..e1eb46a5e9b 100644 --- a/src/vnet/devices/af_packet/device.c +++ b/src/vnet/devices/af_packet/device.c @@ -418,9 +418,10 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm, CLIB_MEMORY_BARRIER (); - if (PREDICT_TRUE (n_sent)) + if (PREDICT_TRUE (n_sent || tx_queue->is_tx_pending)) { tx_queue->next_tx_frame = tx_frame; + tx_queue->is_tx_pending = 0; if (PREDICT_FALSE ( sendto (tx_queue->fd, NULL, 0, MSG_DONTWAIT, NULL, 0) == -1)) @@ -429,11 +430,26 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm, * Note that we have no reliable way to properly determine the * disposition of the packets we just enqueued for delivery. */ - vlib_error_count (vm, node->node_index, - unix_error_is_fatal (errno) ? - AF_PACKET_TX_ERROR_TXRING_FATAL : - AF_PACKET_TX_ERROR_TXRING_EAGAIN, - n_sent); + uword counter; + + if (unix_error_is_fatal (errno)) + { + counter = AF_PACKET_TX_ERROR_TXRING_FATAL; + } + else + { + counter = AF_PACKET_TX_ERROR_TXRING_EAGAIN; + /* non-fatal error: kick again next time + * note that you could still end up in a deadlock: if you do not + * try to send new packets (ie reschedule this tx node), eg. + * because your peer is waiting for the unsent packets to reply + * to you but your waiting for its reply etc., you are not going + * to kick again, and everybody is waiting for the other to talk + * 1st... */ + tx_queue->is_tx_pending = 1; + } + + vlib_error_count (vm, node->node_index, counter, 1); } } |