X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdevices%2Fvirtio%2Fvirtio.c;h=925ad092b91d9c3c272980696cb35baa266843df;hb=bd50ed18d;hp=a3fd05dbb55752609a3754c67efa679d106f6240;hpb=3f340175aebaf84ed3994799e819e0801c7e3212;p=vpp.git diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index a3fd05dbb55..925ad092b91 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include @@ -55,7 +53,8 @@ call_read_ready (clib_file_t * uf) CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b)); if ((qid & 1) == 0) - vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, qid); + vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, + RX_QUEUE_ACCESS (qid)); return 0; } @@ -64,11 +63,7 @@ call_read_ready (clib_file_t * uf) clib_error_t * virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) { - clib_error_t *err = 0; virtio_vring_t *vring; - struct vhost_vring_state state = { 0 }; - struct vhost_vring_addr addr = { 0 }; - struct vhost_vring_file file = { 0 }; clib_file_t t = { 0 }; int i; @@ -87,7 +82,7 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (idx), CLIB_CACHE_LINE_BYTES); vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (idx)); - if (thm->n_vlib_mains > 1) + if (thm->n_vlib_mains > vif->num_txqs) clib_spinlock_init (&vring->lockp); } else @@ -96,19 +91,19 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) CLIB_CACHE_LINE_BYTES); vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (idx)); } - i = sizeof (struct vring_desc) * sz; + i = sizeof (vring_desc_t) * sz; i = round_pow2 (i, CLIB_CACHE_LINE_BYTES); vring->desc = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES); clib_memset (vring->desc, 0, i); - i = sizeof (struct vring_avail) + sz * sizeof (vring->avail->ring[0]); + i = sizeof (vring_avail_t) + sz * sizeof (vring->avail->ring[0]); i = round_pow2 (i, CLIB_CACHE_LINE_BYTES); vring->avail = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES); clib_memset (vring->avail, 0, i); // tell kernel that we don't need interrupt - vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT; + vring->avail->flags = VRING_AVAIL_F_NO_INTERRUPT; - i = sizeof (struct vring_used) + sz * sizeof (struct vring_used_elem); + i = sizeof (vring_used_t) + sz * sizeof (vring_used_elem_t); i = round_pow2 (i, CLIB_CACHE_LINE_BYTES); vring->used = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES); clib_memset (vring->used, 0, i); @@ -117,9 +112,16 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) ASSERT (vring->buffers == 0); vec_validate_aligned (vring->buffers, sz, CLIB_CACHE_LINE_BYTES); + if (idx & 1) + { + clib_memset_u32 (vring->buffers, ~0, sz); + } + vring->size = sz; vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); - vring->kick_fd = eventfd (0, EFD_CLOEXEC); + vring->kick_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); + virtio_log_debug (vif, "vring %u size %u call_fd %d kick_fd %d", idx, + vring->size, vring->call_fd, vring->kick_fd); t.read_function = call_read_ready; t.file_descriptor = vring->call_fd; @@ -128,27 +130,7 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) vif->dev_instance, idx); vring->call_file_index = clib_file_add (&file_main, &t); - state.index = idx; - state.num = sz; - _IOCTL (vif->fd, VHOST_SET_VRING_NUM, &state); - - addr.index = idx; - addr.flags = 0; - addr.desc_user_addr = pointer_to_uword (vring->desc); - addr.avail_user_addr = pointer_to_uword (vring->avail); - addr.used_user_addr = pointer_to_uword (vring->used); - _IOCTL (vif->fd, VHOST_SET_VRING_ADDR, &addr); - - file.index = idx; - file.fd = vring->kick_fd; - _IOCTL (vif->fd, VHOST_SET_VRING_KICK, &file); - file.fd = vring->call_fd; - _IOCTL (vif->fd, VHOST_SET_VRING_CALL, &file); - file.fd = vif->tap_fd; - _IOCTL (vif->fd, VHOST_NET_SET_BACKEND, &file); - -error: - return err; + return 0; } inline void @@ -202,7 +184,7 @@ virtio_free_used_desc (vlib_main_t * vm, virtio_vring_t * vring) while (n_left) { - struct vring_used_elem *e = &vring->used->ring[last & mask]; + vring_used_elem_t *e = &vring->used->ring[last & mask]; u16 slot = e->id; vlib_buffer_free (vm, &vring->buffers[slot], 1); @@ -233,10 +215,49 @@ virtio_vring_free_tx (vlib_main_t * vm, virtio_if_t * vif, u32 idx) if (vring->avail) clib_mem_free (vring->avail); vec_free (vring->buffers); + gro_flow_table_free (vring->flow_table); + virtio_vring_buffering_free (vm, vring->buffering); clib_spinlock_free (&vring->lockp); return 0; } +void +virtio_set_packet_coalesce (virtio_if_t * vif) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vif->hw_if_index); + virtio_vring_t *vring; + vif->packet_coalesce = 1; + vec_foreach (vring, vif->txq_vrings) + { + gro_flow_table_init (&vring->flow_table, + vif->type & (VIRTIO_IF_TYPE_TAP | + VIRTIO_IF_TYPE_PCI), hw->tx_node_index); + } +} + +clib_error_t * +virtio_set_packet_buffering (virtio_if_t * vif, u16 buffering_size) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, vif->hw_if_index); + virtio_vring_t *vring; + clib_error_t *error = 0; + vif->packet_buffering = 1; + + vec_foreach (vring, vif->txq_vrings) + { + if ((error = + virtio_vring_buffering_init (&vring->buffering, hw->tx_node_index, + buffering_size))) + { + break; + } + } + + return error; +} + void virtio_vring_set_numa_node (vlib_main_t * vm, virtio_if_t * vif, u32 idx) { @@ -258,9 +279,9 @@ virtio_set_net_hdr_size (virtio_if_t * vif) { if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF) || vif->features & VIRTIO_FEATURE (VIRTIO_F_VERSION_1)) - vif->virtio_net_hdr_sz = sizeof (struct virtio_net_hdr_v1); + vif->virtio_net_hdr_sz = sizeof (virtio_net_hdr_v1_t); else - vif->virtio_net_hdr_sz = sizeof (struct virtio_net_hdr); + vif->virtio_net_hdr_sz = sizeof (virtio_net_hdr_t); } inline void @@ -311,18 +332,37 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) vlib_cli_output (vm, " PCI Address: %U", format_vlib_pci_addr, &vif->pci_addr); } - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { + u8 *str = 0; if (vif->host_if_name) vlib_cli_output (vm, " name \"%s\"", vif->host_if_name); if (vif->net_ns) vlib_cli_output (vm, " host-ns \"%s\"", vif->net_ns); - vlib_cli_output (vm, " fd %d", vif->fd); - vlib_cli_output (vm, " tap-fd %d", vif->tap_fd); - vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled); + if (vif->host_mtu_size) + vlib_cli_output (vm, " host-mtu-size \"%d\"", + vif->host_mtu_size); + if (type == VIRTIO_IF_TYPE_TAP) + vlib_cli_output (vm, " host-mac-addr: %U", + format_ethernet_address, vif->host_mac_addr); + vlib_cli_output (vm, " host-carrier-up: %u", vif->host_carrier_up); + + vec_foreach_index (i, vif->vhost_fds) + str = format (str, " %d", vif->vhost_fds[i]); + vlib_cli_output (vm, " vhost-fds%v", str); + vec_free (str); + vec_foreach_index (i, vif->tap_fds) + str = format (str, " %d", vif->tap_fds[i]); + vlib_cli_output (vm, " tap-fds%v", str); + vec_free (str); } - vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address, - vif->mac_addr); + vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled); + vlib_cli_output (vm, " csum-enabled %d", vif->csum_offload_enabled); + vlib_cli_output (vm, " packet-coalesce %d", vif->packet_coalesce); + vlib_cli_output (vm, " packet-buffering %d", vif->packet_buffering); + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_PCI)) + vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address, + vif->mac_addr); vlib_cli_output (vm, " Device instance: %u", vif->dev_instance); vlib_cli_output (vm, " flags 0x%x", vif->flags); flag_entry = (struct feat_struct *) &flags_array; @@ -372,7 +412,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); @@ -386,7 +426,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " ===== ================== ===== ====== ===== ==================\n"); for (j = 0; j < vring->size; j++) { - struct vring_desc *desc = &vring->desc[j]; + vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n", j, desc->addr, @@ -407,11 +447,21 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); } + if (vring->flow_table) + { + vlib_cli_output (vm, " %U", gro_flow_table_format, + vring->flow_table); + } + if (vif->packet_buffering) + { + vlib_cli_output (vm, " %U", virtio_vring_buffering_format, + vring->buffering); + } if (show_descr) { vlib_cli_output (vm, "\n descriptor table:\n"); @@ -421,7 +471,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " ===== ================== ===== ====== ===== ==================\n"); for (j = 0; j < vring->size; j++) { - struct vring_desc *desc = &vring->desc[j]; + vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n", j, desc->addr, @@ -443,7 +493,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); @@ -457,7 +507,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " ===== ================== ===== ====== ===== ==================\n"); for (j = 0; j < vring->size; j++) { - struct vring_desc *desc = &vring->desc[j]; + vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n", j, desc->addr, @@ -471,6 +521,20 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } +static clib_error_t * +virtio_init (vlib_main_t * vm) +{ + virtio_main_t *vim = &virtio_main; + clib_error_t *error = 0; + + vim->log_default = vlib_log_register_class ("virtio", 0); + vlib_log_debug (vim->log_default, "initialized"); + + return error; +} + +VLIB_INIT_FUNCTION (virtio_init); + /* * fd.io coding-style-patch-verification: ON *