summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Hawari <mohammed@hawari.fr>2021-09-06 11:48:17 +0200
committerDamjan Marion <dmarion@me.com>2021-09-07 17:14:36 +0000
commiteed6fc9a98e2574a9f39caec512a072e60b0bdb5 (patch)
tree219e45be5232c491ffe8faee6d13962ac503008f
parent0b42ac565b970c186a9ad734f980b440f56fb25b (diff)
devices: restore regular af-packet tx path
This change restores the af_packet tx path prior in use prior to Change Idf0bdd88990254a614962c2f7bc3e0292ccfd61a but fixes the stalling issue by ensuring that the next tx frame pointer is only incremented when a new tx frame is used. This change also enables the af_packet PACKET_QDISC_BYPASS option, for better performance. Change-Id: I65dde648ed66d21654847a900ceda5a8980ae6ec Type: improvement Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
-rw-r--r--src/vnet/devices/af_packet/af_packet.c9
-rw-r--r--src/vnet/devices/af_packet/device.c40
2 files changed, 28 insertions, 21 deletions
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c
index 76677a43092..cace3450e3e 100644
--- a/src/vnet/devices/af_packet/af_packet.c
+++ b/src/vnet/devices/af_packet/af_packet.c
@@ -192,6 +192,15 @@ create_packet_v2_sock (int host_if_index, tpacket_req_t * rx_req,
goto error;
}
+ if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) <
+ 0)
+ {
+ vlib_log_debug (apm->log_class,
+ "Failed to set qdisc bypass error "
+ "handling option: %s (errno %d)",
+ strerror (errno), errno);
+ }
+
if (setsockopt (*fd, SOL_PACKET, PACKET_RX_RING, rx_req, req_sz) < 0)
{
vlib_log_debug (apm->log_class,
diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c
index b6b99a0465c..8a6ff1de649 100644
--- a/src/vnet/devices/af_packet/device.c
+++ b/src/vnet/devices/af_packet/device.c
@@ -149,17 +149,12 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm,
u32 bi = buffers[0];
buffers++;
- nextframe:
tph = (struct tpacket2_hdr *) (block_start + tx_frame * frame_size);
if (PREDICT_FALSE (tph->tp_status &
(TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING)))
{
- tx_frame = (tx_frame + 1) % frame_num;
frame_not_ready++;
- /* check if we've exhausted the ring */
- if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num))
- break;
- goto nextframe;
+ goto next;
}
do
@@ -180,6 +175,7 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm,
tx_frame = (tx_frame + 1) % frame_num;
+ next:
/* check if we've exhausted the ring */
if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num))
break;
@@ -187,22 +183,24 @@ VNET_DEVICE_CLASS_TX_FN (af_packet_device_class) (vlib_main_t * vm,
CLIB_MEMORY_BARRIER ();
- apif->next_tx_frame = tx_frame;
-
if (PREDICT_TRUE (n_sent))
- if (PREDICT_FALSE (sendto (apif->fd, NULL, 0, MSG_DONTWAIT, NULL, 0) ==
- -1))
- {
- /* Uh-oh, drop & move on, but count whether it was fatal or not.
- * 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);
- }
+ {
+ apif->next_tx_frame = tx_frame;
+
+ if (PREDICT_FALSE (sendto (apif->fd, NULL, 0, MSG_DONTWAIT, NULL, 0) ==
+ -1))
+ {
+ /* Uh-oh, drop & move on, but count whether it was fatal or not.
+ * 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);
+ }
+ }
clib_spinlock_unlock_if_init (&apif->lockp);