From: Steven Date: Wed, 10 Oct 2018 04:12:25 +0000 (-0700) Subject: vmxnet3: better error handling X-Git-Tag: v19.04-rc0~640 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=8b0995366110ff8c97d1d10aaa8291ad465b0b2f vmxnet3: better error handling 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 --- diff --git a/src/plugins/vmxnet3/input.c b/src/plugins/vmxnet3/input.c index 4ff459a066a..9392d57747d 100644 --- a/src/plugins/vmxnet3/input.c +++ b/src/plugins/vmxnet3/input.c @@ -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)))) diff --git a/src/plugins/vmxnet3/output.c b/src/plugins/vmxnet3/output.c index bcb02949184..2a8494ed447 100644 --- a/src/plugins/vmxnet3/output.c +++ b/src/plugins/vmxnet3/output.c @@ -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; + } } /*