diff options
Diffstat (limited to 'src/vnet/pg/output.c')
-rw-r--r-- | src/vnet/pg/output.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/vnet/pg/output.c b/src/vnet/pg/output.c index d8059fab186..042591a7709 100644 --- a/src/vnet/pg/output.c +++ b/src/vnet/pg/output.c @@ -42,6 +42,7 @@ #include <vnet/vnet.h> #include <vnet/pg/pg.h> #include <vnet/ethernet/ethernet.h> +#include <vnet/gso/gro_func.h> uword pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) @@ -50,6 +51,8 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) u32 *buffers = vlib_frame_vector_args (frame); uword n_buffers = frame->n_vectors; uword n_left = n_buffers; + u32 to[GRO_TO_VECTOR_SIZE (n_buffers)]; + uword n_to = 0; vnet_interface_output_runtime_t *rd = (void *) node->runtime_data; pg_interface_t *pif = pool_elt_at_index (pg->interfaces, rd->dev_instance); @@ -57,6 +60,13 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) while (clib_atomic_test_and_set (pif->lockp)) ; + if (PREDICT_FALSE (pif->coalesce_enabled)) + { + n_to = vnet_gro_inline (vm, pif->flow_table, buffers, n_left, to); + buffers = to; + n_left = n_to; + } + while (n_left > 0) { n_left--; @@ -84,7 +94,13 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) pif->pcap_main.n_packets_to_capture) pcap_close (&pif->pcap_main); - vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_buffers); + if (PREDICT_FALSE (pif->coalesce_enabled)) + { + n_buffers = n_to; + vlib_buffer_free (vm, to, n_to); + } + else + vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_buffers); if (PREDICT_FALSE (pif->lockp != 0)) clib_atomic_release (pif->lockp); |