devices: restore regular af-packet tx path 69/33669/2
authorMohammed Hawari <mohammed@hawari.fr>
Mon, 6 Sep 2021 09:48:17 +0000 (11:48 +0200)
committerDamjan Marion <dmarion@me.com>
Tue, 7 Sep 2021 17:14:36 +0000 (17:14 +0000)
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>
src/vnet/devices/af_packet/af_packet.c
src/vnet/devices/af_packet/device.c

index 76677a4..cace345 100644 (file)
@@ -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,
index b6b99a0..8a6ff1d 100644 (file)
@@ -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);