From eed6fc9a98e2574a9f39caec512a072e60b0bdb5 Mon Sep 17 00:00:00 2001 From: Mohammed Hawari Date: Mon, 6 Sep 2021 11:48:17 +0200 Subject: 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 --- src/vnet/devices/af_packet/af_packet.c | 9 ++++++++ src/vnet/devices/af_packet/device.c | 40 ++++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src/vnet/devices/af_packet') 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); -- cgit 1.2.3-korg