diff options
author | Steven <sluong@cisco.com> | 2018-10-09 21:12:25 -0700 |
---|---|---|
committer | Steven <sluong@cisco.com> | 2018-10-11 19:59:04 -0700 |
commit | 9864f87b1bd410a6ef533f34b571e28500ee80f7 (patch) | |
tree | f050a95d98c9b7688dc8804da475f9b311c2c492 | |
parent | 125760947a642f0cd5a016deb899a78d83340379 (diff) |
vmxnet3: better error handling [VPP-1449]
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 encountered on input.
Change-Id: I41a45213e29de71935afe707889e515037cd081f
Signed-off-by: Steven <sluong@cisco.com>
(cherry picked from commit 8b0995366110ff8c97d1d10aaa8291ad465b0b2f)
-rw-r--r-- | src/plugins/vmxnet3/input.c | 37 | ||||
-rw-r--r-- | src/plugins/vmxnet3/output.c | 25 |
2 files changed, 42 insertions, 20 deletions
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; + } } /* |