vmxnet3: better error handling 11/15211/2
authorSteven <sluong@cisco.com>
Wed, 10 Oct 2018 04:12:25 +0000 (21:12 -0700)
committerDamjan Marion <dmarion@me.com>
Wed, 10 Oct 2018 16:06:05 +0000 (16:06 +0000)
try harder on output - if there is no descriptor space available, try to free
up some and check again.
make sure we free the buffer if error is encoutered on input.

Change-Id: I41a45213e29de71935afe707889e515037cd081f
Signed-off-by: Steven <sluong@cisco.com>
src/plugins/vmxnet3/input.c
src/plugins/vmxnet3/output.c

index 4ff459a..9392d57 100644 (file)
@@ -27,6 +27,7 @@
   _(BUFFER_ALLOC, "buffer alloc error") \
   _(RX_PACKET_NO_SOP, "Rx packet error - no SOP") \
   _(RX_PACKET, "Rx packet error") \
+  _(RX_PACKET_EOP, "Rx packet error found on EOP") \
   _(NO_BUFFER, "Rx no buffer error")
 
 typedef enum
@@ -79,7 +80,6 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
   uword n_trace = vlib_get_trace_count (vm, node);
   u32 n_rx_packets = 0, n_rx_bytes = 0;
   vmxnet3_rx_comp *rx_comp;
-  u32 comp_idx;
   u32 desc_idx;
   vmxnet3_rxq_t *rxq;
   u32 thread_index = vm->thread_index;
@@ -98,16 +98,14 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
   comp_ring = &rxq->rx_comp_ring;
   bi = buffer_indices;
   next = nexts;
+  rx_comp = &rxq->rx_comp[comp_ring->next];
+
   while (PREDICT_TRUE (n_rx_packets < VLIB_FRAME_SIZE) &&
-        (comp_ring->gen ==
-         (rxq->rx_comp[comp_ring->next].flags & VMXNET3_RXCF_GEN)))
+        (comp_ring->gen == (rx_comp->flags & VMXNET3_RXCF_GEN)))
     {
       vlib_buffer_t *b0;
       u32 bi0;
 
-      comp_idx = comp_ring->next;
-      rx_comp = &rxq->rx_comp[comp_idx];
-
       rid = vmxnet3_find_rid (vd, rx_comp);
       ring = &rxq->rx_ring[rid];
 
@@ -117,10 +115,15 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
        {
          vlib_error_count (vm, node->node_index,
                            VMXNET3_INPUT_ERROR_NO_BUFFER, 1);
+         if (hb)
+           {
+             vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
+             hb = 0;
+           }
+         prev_b0 = 0;
          break;
        }
 
-      vmxnet3_rx_comp_ring_advance_next (rxq);
       desc_idx = rx_comp->index & VMXNET3_RXC_INDEX;
       ring->consume = desc_idx;
       rxd = &rxq->rx_desc[rid][desc_idx];
@@ -146,14 +149,14 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
        {
          vlib_buffer_free_one (vm, bi0);
          vlib_error_count (vm, node->node_index,
-                           VMXNET3_INPUT_ERROR_RX_PACKET, 1);
+                           VMXNET3_INPUT_ERROR_RX_PACKET_EOP, 1);
          if (hb && vlib_get_buffer_index (vm, hb) != bi0)
            {
              vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
              hb = 0;
            }
          prev_b0 = 0;
-         continue;
+         goto next;
        }
 
       if (rx_comp->index & VMXNET3_RXCI_SOP)
@@ -199,7 +202,7 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                  vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
                  hb = 0;
                }
-             continue;
+             goto next;
            }
        }
       else if (prev_b0)                // !sop && !eop
@@ -213,7 +216,15 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
        }
       else
        {
-         ASSERT (0);
+         vlib_error_count (vm, node->node_index,
+                           VMXNET3_INPUT_ERROR_RX_PACKET, 1);
+         vlib_buffer_free_one (vm, bi0);
+         if (hb && vlib_get_buffer_index (vm, hb) != bi0)
+           {
+             vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
+             hb = 0;
+           }
+         goto next;
        }
 
       n_rx_bytes += b0->current_length;
@@ -275,6 +286,10 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          hb = 0;
          got_packet = 0;
        }
+
+    next:
+      vmxnet3_rx_comp_ring_advance_next (rxq);
+      rx_comp = &rxq->rx_comp[comp_ring->next];
     }
 
   if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node))))
index bcb0294..2a8494e 100644 (file)
@@ -143,15 +143,22 @@ VNET_DEVICE_CLASS_TX_FN (vmxnet3_device_class) (vlib_main_t * vm,
        }
       if (PREDICT_FALSE (space_left < space_needed))
        {
-         vlib_buffer_free_one (vm, bi0);
-         vlib_error_count (vm, node->node_index,
-                           VMXNET3_TX_ERROR_NO_FREE_SLOTS, 1);
-         buffers++;
-         n_left--;
-         /*
-          * Drop this packet. But we may have enough room for the next packet
-          */
-         continue;
+         vmxnet3_txq_release (vm, vd, txq);
+         space_left = vmxnet3_tx_ring_space_left (txq);
+
+         if (PREDICT_FALSE (space_left < space_needed))
+           {
+             vlib_buffer_free_one (vm, bi0);
+             vlib_error_count (vm, node->node_index,
+                               VMXNET3_TX_ERROR_NO_FREE_SLOTS, 1);
+             buffers++;
+             n_left--;
+             /*
+              * Drop this packet. But we may have enough room for the next
+              * packet
+              */
+             continue;
+           }
        }
 
       /*