X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvnet%2Fdevices%2Fvirtio%2Fvhost_user_output.c;h=d3e38bfa04e9a98f7afa7a0c7b310b31ce0f0465;hb=38071b1331b44746679997f6e66081c4936d087c;hp=465c0ea090394eb0c2a78679b3642fdace758d5d;hpb=27ba5008a16eddccc0b285272de7f89fd0aa3a24;p=vpp.git diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index 465c0ea0903..d3e38bfa04e 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -194,8 +194,8 @@ vhost_user_tx_copy (vhost_user_intf_t * vui, vhost_copy_t * cpy, (!(dst3 = map_guest_mem (vui, cpy[3].dst, map_hint)))) return 1; - CLIB_PREFETCH ((void *) cpy[2].src, 64, LOAD); - CLIB_PREFETCH ((void *) cpy[3].src, 64, LOAD); + clib_prefetch_load ((void *) cpy[2].src); + clib_prefetch_load ((void *) cpy[3].src); clib_memcpy_fast (dst0, (void *) cpy[0].src, cpy[0].len); clib_memcpy_fast (dst1, (void *) cpy[1].src, cpy[1].len); @@ -225,10 +225,11 @@ vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, generic_header_offset_t gho = { 0 }; int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4; int is_ip6 = b->flags & VNET_BUFFER_F_IS_IP6; + vnet_buffer_oflags_t oflags = vnet_buffer (b)->oflags; ASSERT (!(is_ip4 && is_ip6)); vnet_generic_header_offset_parser (b, &gho, 1 /* l2 */ , is_ip4, is_ip6); - if (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM) + if (oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM) { ip4_header_t *ip4; @@ -238,13 +239,13 @@ vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, } /* checksum offload */ - if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) + if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM) { hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->csum_start = gho.l4_hdr_offset; hdr->csum_offset = offsetof (udp_header_t, checksum); } - else if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + else if (oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM) { hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; hdr->csum_start = gho.l4_hdr_offset; @@ -254,7 +255,7 @@ vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, /* GSO offload */ if (b->flags & VNET_BUFFER_F_GSO) { - if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + if (oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM) { if (is_ip4 && (vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4))) @@ -270,7 +271,7 @@ vhost_user_handle_tx_offload (vhost_user_intf_t * vui, vlib_buffer_t * b, } } else if ((vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)) && - (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM)) + (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM)) { hdr->gso_size = vnet_buffer2 (b)->gso_size; hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; @@ -477,9 +478,7 @@ retry: hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE; hdr->num_buffers = 1; - or_flags = (b0->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM) || - (b0->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) || - (b0->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM); + or_flags = (b0->flags & VNET_BUFFER_F_OFFLOAD); /* Guest supports csum offload and buffer requires checksum offload? */ if (or_flags && @@ -602,7 +601,7 @@ retry: buffer_map_addr += cpy->len; desc_len += cpy->len; - CLIB_PREFETCH (&rxvq->packed_desc, CLIB_CACHE_LINE_BYTES, LOAD); + clib_prefetch_load (&rxvq->packed_desc); /* Check if vlib buffer has more data. If not, get more or break */ if (PREDICT_TRUE (!bytes_left)) @@ -813,9 +812,7 @@ retry: hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE; hdr->num_buffers = 1; //This is local, no need to check - or_flags = (b0->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM) || - (b0->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) || - (b0->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM); + or_flags = (b0->flags & VNET_BUFFER_F_OFFLOAD); /* Guest supports csum offload and buffer requires checksum offload? */ if (or_flags @@ -925,7 +922,7 @@ retry: buffer_map_addr += cpy->len; desc_len += cpy->len; - CLIB_PREFETCH (&rxvq->desc, CLIB_CACHE_LINE_BYTES, LOAD); + clib_prefetch_load (&rxvq->desc); } // Check if vlib buffer has more data. If not, get more or break. @@ -1049,7 +1046,24 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, vhost_user_intf_t *vui = pool_elt_at_index (vum->vhost_user_interfaces, hif->dev_instance); vhost_user_vring_t *txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)]; + vhost_cpu_t *cpu; + if (mode == txvq->mode) + return 0; + + if ((mode != VNET_HW_IF_RX_MODE_POLLING) && + (mode != VNET_HW_IF_RX_MODE_ADAPTIVE) && + (mode != VNET_HW_IF_RX_MODE_INTERRUPT)) + { + vu_log_err (vui, "unhandled mode %d changed for if %d queue %d", mode, + hw_if_index, qid); + return clib_error_return (0, "unsupported"); + } + + if (txvq->thread_index == ~0) + return clib_error_return (0, "Queue initialization is not finished yet"); + + cpu = vec_elt_at_index (vum->cpus, txvq->thread_index); if ((mode == VNET_HW_IF_RX_MODE_INTERRUPT) || (mode == VNET_HW_IF_RX_MODE_ADAPTIVE)) { @@ -1060,11 +1074,14 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, } if (txvq->mode == VNET_HW_IF_RX_MODE_POLLING) { + ASSERT (cpu->polling_q_count != 0); + if (cpu->polling_q_count) + cpu->polling_q_count--; vum->ifq_count++; // Start the timer if this is the first encounter on interrupt // interface/queue if ((vum->ifq_count == 1) && - (vum->coalesce_time > 0.0) && (vum->coalesce_frames > 0)) + ((vum->coalesce_time > 0.0) || (vum->coalesce_frames > 0))) vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index, VHOST_USER_EVENT_START_TIMER, 0); @@ -1075,10 +1092,10 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, if (((txvq->mode == VNET_HW_IF_RX_MODE_INTERRUPT) || (txvq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)) && vum->ifq_count) { + cpu->polling_q_count++; vum->ifq_count--; // Stop the timer if there is no more interrupt interface/queue - if ((vum->ifq_count == 0) && - (vum->coalesce_time > 0.0) && (vum->coalesce_frames > 0)) + if (vum->ifq_count == 0) vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index, VHOST_USER_EVENT_STOP_TIMER, 0); @@ -1086,17 +1103,7 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, } txvq->mode = mode; - if (mode == VNET_HW_IF_RX_MODE_POLLING) - txvq->used->flags = VRING_USED_F_NO_NOTIFY; - else if ((mode == VNET_HW_IF_RX_MODE_ADAPTIVE) || - (mode == VNET_HW_IF_RX_MODE_INTERRUPT)) - txvq->used->flags = 0; - else - { - vu_log_err (vui, "unhandled mode %d changed for if %d queue %d", mode, - hw_if_index, qid); - return clib_error_return (0, "unsupported"); - } + vhost_user_set_operation_mode (vui, txvq); return 0; }