summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/ixge/ixge.c1
-rw-r--r--src/vnet/interface.c8
-rw-r--r--src/vnet/interface.h3
-rw-r--r--src/vnet/interface_funcs.h3
-rw-r--r--src/vnet/interface_output.c265
5 files changed, 3 insertions, 277 deletions
diff --git a/src/plugins/ixge/ixge.c b/src/plugins/ixge/ixge.c
index 0d287250ca4..628d6d71bd7 100644
--- a/src/plugins/ixge/ixge.c
+++ b/src/plugins/ixge/ixge.c
@@ -2454,7 +2454,6 @@ VNET_DEVICE_CLASS (ixge_device_class) = {
.clear_counters = ixge_clear_hw_interface_counters,
.admin_up_down_function = ixge_interface_admin_up_down,
.rx_redirect_to_node = ixge_set_interface_next_node,
- .flatten_output_chains = 1,
};
/* *INDENT-ON* */
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index 1370d048b0b..7c0272b458d 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -783,9 +783,7 @@ vnet_register_interface (vnet_main_t * vnm,
/* The new class may differ from the old one.
* Functions have to be updated. */
node = vlib_get_node (vm, hw->output_node_index);
- node->function = dev_class->flatten_output_chains ?
- vnet_interface_output_node_flatten_multiarch_select () :
- vnet_interface_output_node_multiarch_select ();
+ node->function = vnet_interface_output_node_multiarch_select ();
node->format_trace = format_vnet_interface_output_trace;
nrt = vlib_node_get_runtime (vm, hw->output_node_index);
nrt->function = node->function;
@@ -827,9 +825,7 @@ vnet_register_interface (vnet_main_t * vnm,
r.flags = 0;
r.name = output_node_name;
- r.function = dev_class->flatten_output_chains ?
- vnet_interface_output_node_flatten_multiarch_select () :
- vnet_interface_output_node_multiarch_select ();
+ r.function = vnet_interface_output_node_multiarch_select ();
r.format_trace = format_vnet_interface_output_trace;
{
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index d684e356ca4..ce7700e4ee0 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -198,9 +198,6 @@ typedef struct _vnet_device_class
/* Link-list of all device classes set up by constructors created below */
struct _vnet_device_class *next_class_registration;
- /* Splice vnet_interface_output_node into TX path */
- u8 flatten_output_chains;
-
/* Function to set mac address. */
vnet_interface_set_mac_address_function_t *mac_addr_change_function;
} vnet_device_class_t;
diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h
index 999b72e5a3c..26eef9b9d87 100644
--- a/src/vnet/interface_funcs.h
+++ b/src/vnet/interface_funcs.h
@@ -301,9 +301,8 @@ typedef struct
u32 is_deleted;
} vnet_interface_output_runtime_t;
-/* Interface output functions. */
+/* Interface output function. */
void *vnet_interface_output_node_multiarch_select (void);
-void *vnet_interface_output_node_flatten_multiarch_select (void);
word vnet_sw_interface_compare (vnet_main_t * vnm, uword sw_if_index0,
uword sw_if_index1);
diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c
index 846eb57b95e..cdf18738193 100644
--- a/src/vnet/interface_output.c
+++ b/src/vnet/interface_output.c
@@ -153,271 +153,6 @@ vnet_interface_output_trace (vlib_main_t * vm,
}
}
-static never_inline u32
-slow_path (vlib_main_t * vm,
- u32 bi,
- vlib_buffer_t * b,
- u32 n_left_to_tx, u32 * to_tx, u32 * n_slow_bytes_result)
-{
- /* We've already enqueued a single buffer. */
- u32 n_buffers = 0;
- u32 n_slow_bytes = 0;
-
- while (n_left_to_tx > 0)
- {
- to_tx[0] = bi;
- to_tx += 1;
- n_left_to_tx -= 1;
- n_buffers += 1;
- n_slow_bytes += vlib_buffer_length_in_chain (vm, b);
-
- /* Be grumpy about zero length buffers for benefit of
- driver tx function. */
- ASSERT (b->current_length > 0);
-
- if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT))
- break;
-
- bi = b->next_buffer;
- b = vlib_get_buffer (vm, bi);
- }
-
- /* Ran out of space in next frame trying to enqueue buffers? */
- if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
- return 0;
-
- *n_slow_bytes_result = n_slow_bytes;
- return n_buffers;
-}
-
-/*
- * Increment TX stats. Roll up consecutive increments to the same sw_if_index
- * into one increment.
- */
-static_always_inline void
-incr_output_stats (vnet_main_t * vnm,
- u32 thread_index,
- u32 length,
- u32 sw_if_index,
- u32 * last_sw_if_index, u32 * n_packets, u32 * n_bytes)
-{
- vnet_interface_main_t *im;
-
- if (PREDICT_TRUE (sw_if_index == *last_sw_if_index))
- {
- *n_packets += 1;
- *n_bytes += length;
- }
- else
- {
- if (PREDICT_TRUE (*last_sw_if_index != ~0))
- {
- im = &vnm->interface_main;
-
- vlib_increment_combined_counter (im->combined_sw_if_counters
- + VNET_INTERFACE_COUNTER_TX,
- thread_index,
- *last_sw_if_index,
- *n_packets, *n_bytes);
- }
- *last_sw_if_index = sw_if_index;
- *n_packets = 1;
- *n_bytes = length;
- }
-}
-
-
-/* Interface output functions. */
-uword
-vnet_interface_output_node_flatten (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- vnet_main_t *vnm = vnet_get_main ();
- vnet_interface_output_runtime_t *rt = (void *) node->runtime_data;
- vnet_sw_interface_t *si;
- vnet_hw_interface_t *hi;
- u32 n_left_to_tx, *from, *from_end, *to_tx;
- u32 n_bytes, n_buffers, n_packets;
- u32 last_sw_if_index;
- u32 thread_index = vm->thread_index;
-
- n_buffers = frame->n_vectors;
-
- if (node->flags & VLIB_NODE_FLAG_TRACE)
- vnet_interface_output_trace (vm, node, frame, n_buffers);
-
- from = vlib_frame_args (frame);
-
- if (rt->is_deleted)
- return vlib_error_drop_buffers (vm, node, from,
- /* buffer stride */ 1,
- n_buffers,
- VNET_INTERFACE_OUTPUT_NEXT_DROP,
- node->node_index,
- VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED);
-
- si = vnet_get_sw_interface (vnm, rt->sw_if_index);
- hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index);
- if (!(si->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP |
- VNET_SW_INTERFACE_FLAG_BOND_SLAVE)) ||
- !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
- {
- vlib_simple_counter_main_t *cm;
-
- cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
- VNET_INTERFACE_COUNTER_TX_ERROR);
- vlib_increment_simple_counter (cm, thread_index,
- rt->sw_if_index, n_buffers);
- return vlib_error_drop_buffers (vm, node, from,
- /* buffer stride */ 1,
- n_buffers,
- VNET_INTERFACE_OUTPUT_NEXT_DROP,
- node->node_index,
- VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN);
- }
-
- from_end = from + n_buffers;
-
- /* Total byte count of all buffers. */
- n_bytes = 0;
- n_packets = 0;
- last_sw_if_index = ~0;
-
- while (from < from_end)
- {
- /* Get new next frame since previous incomplete frame may have less
- than VNET_FRAME_SIZE vectors in it. */
- vlib_get_new_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX,
- to_tx, n_left_to_tx);
-
- while (from + 4 <= from_end && n_left_to_tx >= 2)
- {
- u32 bi0, bi1;
- vlib_buffer_t *b0, *b1;
-
- /* Prefetch next iteration. */
- vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
- vlib_prefetch_buffer_with_index (vm, from[3], LOAD);
-
- bi0 = from[0];
- bi1 = from[1];
- to_tx[0] = bi0;
- to_tx[1] = bi1;
- from += 2;
- to_tx += 2;
- n_left_to_tx -= 2;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
-
- /* Be grumpy about zero length buffers for benefit of
- driver tx function. */
- ASSERT (b0->current_length > 0);
- ASSERT (b1->current_length > 0);
-
- if (PREDICT_FALSE
- ((b0->flags | b1->flags) & VLIB_BUFFER_NEXT_PRESENT))
- {
- u32 n_buffers, n_slow_bytes, i;
-
- /* Undo. */
- from -= 2;
- to_tx -= 2;
- n_left_to_tx += 2;
-
- /* Do slow path two times. */
- for (i = 0; i < 2; i++)
- {
- u32 bi = i ? bi1 : bi0;
- vlib_buffer_t *b = i ? b1 : b0;
-
- n_buffers = slow_path (vm, bi, b,
- n_left_to_tx, to_tx, &n_slow_bytes);
-
- /* Not enough room for single packet? */
- if (n_buffers == 0)
- goto put;
-
- from += 1;
- to_tx += n_buffers;
- n_left_to_tx -= n_buffers;
- incr_output_stats (vnm, thread_index, n_slow_bytes,
- vnet_buffer (b)->sw_if_index[VLIB_TX],
- &last_sw_if_index, &n_packets, &n_bytes);
- }
- }
- else
- {
- incr_output_stats (vnm, thread_index,
- vlib_buffer_length_in_chain (vm, b0),
- vnet_buffer (b0)->sw_if_index[VLIB_TX],
- &last_sw_if_index, &n_packets, &n_bytes);
- incr_output_stats (vnm, thread_index,
- vlib_buffer_length_in_chain (vm, b0),
- vnet_buffer (b1)->sw_if_index[VLIB_TX],
- &last_sw_if_index, &n_packets, &n_bytes);
- }
- }
-
- while (from + 1 <= from_end && n_left_to_tx >= 1)
- {
- u32 bi0;
- vlib_buffer_t *b0;
-
- bi0 = from[0];
- to_tx[0] = bi0;
- from += 1;
- to_tx += 1;
- n_left_to_tx -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- /* Be grumpy about zero length buffers for benefit of
- driver tx function. */
- ASSERT (b0->current_length > 0);
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_NEXT_PRESENT))
- {
- u32 n_buffers, n_slow_bytes;
-
- /* Undo. */
- from -= 1;
- to_tx -= 1;
- n_left_to_tx += 1;
-
- n_buffers = slow_path (vm, bi0, b0,
- n_left_to_tx, to_tx, &n_slow_bytes);
-
- /* Not enough room for single packet? */
- if (n_buffers == 0)
- goto put;
-
- from += 1;
- to_tx += n_buffers;
- n_left_to_tx -= n_buffers;
- }
- incr_output_stats (vnm, thread_index,
- vlib_buffer_length_in_chain (vm, b0),
- vnet_buffer (b0)->sw_if_index[VLIB_TX],
- &last_sw_if_index, &n_packets, &n_bytes);
- }
-
- put:
- vlib_put_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX,
- n_left_to_tx);
- }
-
- /* Final update of interface stats. */
- incr_output_stats (vnm, thread_index, 0, ~0, /* ~0 will flush stats */
- &last_sw_if_index, &n_packets, &n_bytes);
-
- return n_buffers;
-}
-
-VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node_flatten);
-CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node_flatten);
-
uword
vnet_interface_output_node (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * frame)