diff options
Diffstat (limited to 'src/vnet/devices/virtio/device.c')
-rw-r--r-- | src/vnet/devices/virtio/device.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index 45c390d415d..99157cd6166 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -23,6 +23,7 @@ #include <vlib/unix/unix.h> #include <vnet/vnet.h> #include <vnet/ethernet/ethernet.h> +#include <vnet/gso/gro_func.h> #include <vnet/gso/hdr_offset_parser.h> #include <vnet/ip/ip4_packet.h> #include <vnet/ip/ip6_packet.h> @@ -502,7 +503,7 @@ static_always_inline uword virtio_interface_tx_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, virtio_if_t * vif, virtio_if_type_t type, int do_gso, - int csum_offload) + int csum_offload, int do_gro) { u16 n_left = frame->n_vectors; virtio_vring_t *vring; @@ -513,6 +514,7 @@ virtio_interface_tx_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u16 mask = sz - 1; u16 retry_count = 2; u32 *buffers = vlib_frame_vector_args (frame); + u32 to[GRO_TO_VECTOR_SIZE (n_left)]; clib_spinlock_lock_if_init (&vring->lockp); @@ -520,6 +522,12 @@ virtio_interface_tx_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, (vring->last_kick_avail_idx != vring->avail->idx)) virtio_kick (vm, vring, vif); + if (do_gro) + { + n_left = vnet_gro_inline (vm, vring->flow_table, buffers, n_left, to); + buffers = to; + } + retry: /* free consumed buffers */ virtio_free_used_device_desc (vm, vring, node->node_index); @@ -621,7 +629,8 @@ retry: if (retry_count--) goto retry; - virtio_interface_drop_inline (vm, node->node_index, buffers, n_left, + virtio_interface_drop_inline (vm, node->node_index, + buffers, n_left, VIRTIO_TX_ERROR_NO_FREE_SLOTS); } @@ -641,15 +650,18 @@ virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (hw->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO) return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, 1 /* do_gso */ , - 1 /* checksum offload */ ); + 1 /* checksum offload */ , + vif->packet_coalesce); else if (hw->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD) return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, 0 /* no do_gso */ , - 1 /* checksum offload */ ); + 1 /* checksum offload */ , + 0 /* do_gro */ ); else return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, 0 /* no do_gso */ , - 0 /* no checksum offload */ ); + 0 /* no checksum offload */ , + 0 /* do_gro */ ); } VNET_DEVICE_CLASS_TX_FN (virtio_device_class) (vlib_main_t * vm, @@ -717,9 +729,16 @@ virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, } if (mode == VNET_HW_INTERFACE_RX_MODE_POLLING) - vring->avail->flags |= VIRTIO_RING_FLAG_MASK_INT; + { + /* only enable packet coalesce in poll mode */ + gro_flow_table_set_is_enable (vring->flow_table, 1); + vring->avail->flags |= VIRTIO_RING_FLAG_MASK_INT; + } else - vring->avail->flags &= ~VIRTIO_RING_FLAG_MASK_INT; + { + gro_flow_table_set_is_enable (vring->flow_table, 0); + vring->avail->flags &= ~VIRTIO_RING_FLAG_MASK_INT; + } return 0; } |