diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/devices/virtio/device.c | 68 |
1 files changed, 32 insertions, 36 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index bc89ca94200..b84949ca3ae 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -541,9 +541,9 @@ virtio_find_free_desc (virtio_vring_t * vring, u16 size, u16 mask, } } -static_always_inline uword +static_always_inline u16 virtio_interface_tx_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, virtio_if_t * vif, + virtio_if_t * vif, virtio_if_type_t type, virtio_vring_t * vring, u32 * buffers, u16 n_left, int do_gso, int csum_offload) @@ -551,6 +551,7 @@ virtio_interface_tx_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u16 used, next, avail, n_buffers = 0, n_buffers_left = 0; u16 sz = vring->size; u16 mask = sz - 1; + u16 n_vectors = n_left; u16 retry_count = 2; retry: @@ -634,7 +635,7 @@ retry: free_desc_count -= n_added; } - if (n_left != frame->n_vectors || n_buffers != n_buffers_left) + if (n_left != n_vectors || n_buffers != n_buffers_left) { CLIB_MEMORY_STORE_BARRIER (); vring->avail->idx = avail; @@ -644,32 +645,15 @@ retry: virtio_kick (vm, vring, vif); } - if (n_left) - { - if (retry_count--) - goto retry; - - if (vif->packet_buffering) - { - - u16 n_buffered = - virtio_vring_buffering_store_packets (vring->buffering, buffers, - n_left); - buffers += n_buffered; - n_left -= n_buffered; - } - if (n_left) - virtio_interface_drop_inline (vm, node->node_index, - buffers, n_left, - VIRTIO_TX_ERROR_NO_FREE_SLOTS); - } + if (n_left && retry_count--) + goto retry; - return frame->n_vectors - n_left; + return n_left; } -static_always_inline uword +static_always_inline u16 virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, virtio_if_t * vif, + virtio_if_t * vif, virtio_vring_t * vring, virtio_if_type_t type, u32 * buffers, u16 n_left) { @@ -677,16 +661,16 @@ virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vif->hw_if_index); if (hw->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO) - return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, vring, + return virtio_interface_tx_gso_inline (vm, node, vif, type, vring, buffers, n_left, 1 /* do_gso */ , 1 /* checksum offload */ ); else if (hw->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD) - return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, vring, + return virtio_interface_tx_gso_inline (vm, node, vif, type, vring, buffers, n_left, 0 /* no do_gso */ , 1 /* checksum offload */ ); else - return virtio_interface_tx_gso_inline (vm, node, frame, vif, type, vring, + return virtio_interface_tx_gso_inline (vm, node, vif, type, vring, buffers, n_left, 0 /* no do_gso */ , 0 /* no checksum offload */ ); @@ -704,7 +688,6 @@ VNET_DEVICE_CLASS_TX_FN (virtio_device_class) (vlib_main_t * vm, u16 n_left = frame->n_vectors; u32 *buffers = vlib_frame_vector_args (frame); u32 to[GRO_TO_VECTOR_SIZE (n_left)]; - uword rv = 0; clib_spinlock_lock_if_init (&vring->lockp); @@ -719,20 +702,33 @@ VNET_DEVICE_CLASS_TX_FN (virtio_device_class) (vlib_main_t * vm, } if (vif->type == VIRTIO_IF_TYPE_TAP) - rv = virtio_interface_tx_inline (vm, node, frame, vif, vring, - VIRTIO_IF_TYPE_TAP, buffers, n_left); + n_left = virtio_interface_tx_inline (vm, node, vif, vring, + VIRTIO_IF_TYPE_TAP, buffers, n_left); else if (vif->type == VIRTIO_IF_TYPE_PCI) - rv = virtio_interface_tx_inline (vm, node, frame, vif, vring, - VIRTIO_IF_TYPE_PCI, buffers, n_left); + n_left = virtio_interface_tx_inline (vm, node, vif, vring, + VIRTIO_IF_TYPE_PCI, buffers, n_left); else if (vif->type == VIRTIO_IF_TYPE_TUN) - rv = virtio_interface_tx_inline (vm, node, frame, vif, vring, - VIRTIO_IF_TYPE_TUN, buffers, n_left); + n_left = virtio_interface_tx_inline (vm, node, vif, vring, + VIRTIO_IF_TYPE_TUN, buffers, n_left); else ASSERT (0); + if (vif->packet_buffering && n_left) + { + u16 n_buffered = + virtio_vring_buffering_store_packets (vring->buffering, buffers, + n_left); + buffers += n_buffered; + n_left -= n_buffered; + } + if (n_left) + virtio_interface_drop_inline (vm, node->node_index, + buffers, n_left, + VIRTIO_TX_ERROR_NO_FREE_SLOTS); + clib_spinlock_unlock_if_init (&vring->lockp); - return rv; + return frame->n_vectors - n_left; } static void |