diff options
Diffstat (limited to 'src/vnet/devices/virtio/virtio.c')
-rw-r--r-- | src/vnet/devices/virtio/virtio.c | 137 |
1 files changed, 84 insertions, 53 deletions
diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index b8054d13e5b..d2302fa1dc4 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -19,7 +19,11 @@ #include <sys/stat.h> #include <fcntl.h> #include <net/if.h> +#ifdef __linux__ #include <linux/if_tun.h> +#elif __FreeBSD__ +#include <net/if_tun.h> +#endif /* __linux__ */ #include <sys/ioctl.h> #include <sys/eventfd.h> @@ -33,6 +37,7 @@ #include <vnet/devices/virtio/virtio_inline.h> #include <vnet/devices/virtio/pci.h> #include <vnet/interface/rx_queue_funcs.h> +#include <vnet/interface/tx_queue_funcs.h> virtio_main_t virtio_main; @@ -59,7 +64,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) { - virtio_vring_t *vring; + vnet_virtio_vring_t *vring; int i; if (!is_pow2 (sz)) @@ -73,12 +78,10 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) if (idx % 2) { - vlib_thread_main_t *thm = vlib_get_thread_main (); 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 > vif->num_txqs) - clib_spinlock_init (&vring->lockp); + clib_spinlock_init (&vring->lockp); } else { @@ -86,19 +89,20 @@ 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 (vring_desc_t) * sz; + i = sizeof (vnet_virtio_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 (vring_avail_t) + sz * sizeof (vring->avail->ring[0]); + i = sizeof (vnet_virtio_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 = VRING_AVAIL_F_NO_INTERRUPT; - i = sizeof (vring_used_t) + sz * sizeof (vring_used_elem_t); + i = sizeof (vnet_virtio_vring_used_t) + + sz * sizeof (vnet_virtio_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); @@ -116,20 +120,21 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) else vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); - vring->size = sz; + vring->total_packets = 0; + vring->queue_size = sz; 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); + vring->queue_size, vring->call_fd, vring->kick_fd); return 0; } inline void -virtio_free_buffers (vlib_main_t * vm, virtio_vring_t * vring) +virtio_free_buffers (vlib_main_t *vm, vnet_virtio_vring_t *vring) { u16 used = vring->desc_in_use; u16 last = vring->last_used_idx; - u16 mask = vring->size - 1; + u16 mask = vring->queue_size - 1; while (used) { @@ -142,7 +147,7 @@ virtio_free_buffers (vlib_main_t * vm, virtio_vring_t * vring) clib_error_t * virtio_vring_free_rx (vlib_main_t * vm, virtio_if_t * vif, u32 idx) { - virtio_vring_t *vring = + vnet_virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (idx)); clib_file_del_by_index (&file_main, vring->call_file_index); @@ -164,7 +169,7 @@ virtio_vring_free_rx (vlib_main_t * vm, virtio_if_t * vif, u32 idx) clib_error_t * virtio_vring_free_tx (vlib_main_t * vm, virtio_if_t * vif, u32 idx) { - virtio_vring_t *vring = + vnet_virtio_vring_t *vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (idx)); close (vring->kick_fd); @@ -189,7 +194,7 @@ 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; + vnet_virtio_vring_t *vring; vif->packet_coalesce = 1; vec_foreach (vring, vif->txq_vrings) { @@ -204,9 +209,8 @@ 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; + vnet_virtio_vring_t *vring; clib_error_t *error = 0; - vif->packet_buffering = 1; vec_foreach (vring, vif->txq_vrings) { @@ -222,7 +226,8 @@ virtio_set_packet_buffering (virtio_if_t * vif, u16 buffering_size) } static void -virtio_vring_fill (vlib_main_t *vm, virtio_if_t *vif, virtio_vring_t *vring) +virtio_vring_fill (vlib_main_t *vm, virtio_if_t *vif, + vnet_virtio_vring_t *vring) { if (vif->is_packed) virtio_refill_vring_packed (vm, vif, vif->type, vring, @@ -238,7 +243,7 @@ void virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif) { vnet_main_t *vnm = vnet_get_main (); - virtio_vring_t *vring; + vnet_virtio_vring_t *vring; u32 i = 0; vnet_hw_if_set_input_node (vnm, vif->hw_if_index, virtio_input_node.index); @@ -284,24 +289,53 @@ virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif) vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index); } +void +virtio_vring_set_tx_queues (vlib_main_t *vm, virtio_if_t *vif) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_virtio_vring_t *vring; + + vec_foreach (vring, vif->txq_vrings) + { + vring->queue_index = vnet_hw_if_register_tx_queue ( + vnm, vif->hw_if_index, TX_QUEUE_ACCESS (vring->queue_id)); + } + + if (vif->num_txqs == 0) + { + virtio_log_error (vif, "Interface %U has 0 txq", + format_vnet_hw_if_index_name, vnm, vif->hw_if_index); + return; + } + + for (u32 j = 0; j < vlib_get_n_threads (); j++) + { + u32 qi = vif->txq_vrings[j % vif->num_txqs].queue_index; + vnet_hw_if_tx_queue_assign_thread (vnm, qi, j); + } + + vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index); +} + inline void 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 (virtio_net_hdr_v1_t); + vif->virtio_net_hdr_sz = sizeof (vnet_virtio_net_hdr_v1_t); else - vif->virtio_net_hdr_sz = sizeof (virtio_net_hdr_t); + vif->virtio_net_hdr_sz = sizeof (vnet_virtio_net_hdr_t); } inline void -virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) +virtio_show (vlib_main_t *vm, u32 *hw_if_indices, u8 show_descr, + virtio_if_type_t type) { u32 i, j, hw_if_index; virtio_if_t *vif; vnet_main_t *vnm = &vnet_main; virtio_main_t *mm = &virtio_main; - virtio_vring_t *vring; + vnet_virtio_vring_t *vring; struct feat_struct { u8 bit; @@ -407,17 +441,17 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } vlib_cli_output (vm, " Number of RX Virtqueue %u", vif->num_rxqs); vlib_cli_output (vm, " Number of TX Virtqueue %u", vif->num_txqs); - if (vif->cxq_vring != NULL - && vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) + if (type == VIRTIO_IF_TYPE_PCI && vif->cxq_vring != NULL && + vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) vlib_cli_output (vm, " Number of CTRL Virtqueue 1"); vec_foreach_index (i, vif->rxq_vrings) { vring = vec_elt_at_index (vif->rxq_vrings, i); vlib_cli_output (vm, " Virtqueue (RX) %d", vring->queue_id); - vlib_cli_output (vm, - " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", - vring->size, vring->last_used_idx, vring->desc_next, - vring->desc_in_use); + vlib_cli_output ( + vm, " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", + vring->queue_size, vring->last_used_idx, vring->desc_next, + vring->desc_in_use); if (vif->is_packed) { vlib_cli_output (vm, @@ -448,11 +482,12 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " id addr len flags next/id user_addr\n"); vlib_cli_output (vm, " ===== ================== ===== ====== ======= ==================\n"); - for (j = 0; j < vring->size; j++) + for (j = 0; j < vring->queue_size; j++) { if (vif->is_packed) { - vring_packed_desc_t *desc = &vring->packed_desc[j]; + vnet_virtio_vring_packed_desc_t *desc = + &vring->packed_desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -461,7 +496,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } else { - vring_desc_t *desc = &vring->desc[j]; + vnet_virtio_vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -475,10 +510,10 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) { vring = vec_elt_at_index (vif->txq_vrings, i); vlib_cli_output (vm, " Virtqueue (TX) %d", vring->queue_id); - vlib_cli_output (vm, - " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", - vring->size, vring->last_used_idx, vring->desc_next, - vring->desc_in_use); + vlib_cli_output ( + vm, " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", + vring->queue_size, vring->last_used_idx, vring->desc_next, + vring->desc_in_use); if (vif->is_packed) { vlib_cli_output (vm, @@ -519,11 +554,12 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " id addr len flags next/id user_addr\n"); vlib_cli_output (vm, " ===== ================== ===== ====== ======== ==================\n"); - for (j = 0; j < vring->size; j++) + for (j = 0; j < vring->queue_size; j++) { if (vif->is_packed) { - vring_packed_desc_t *desc = &vring->packed_desc[j]; + vnet_virtio_vring_packed_desc_t *desc = + &vring->packed_desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -532,7 +568,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } else { - vring_desc_t *desc = &vring->desc[j]; + vnet_virtio_vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -542,15 +578,15 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } } } - if (vif->cxq_vring != NULL - && vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) + if (type == VIRTIO_IF_TYPE_PCI && vif->cxq_vring != NULL && + vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) { vring = vif->cxq_vring; vlib_cli_output (vm, " Virtqueue (CTRL) %d", vring->queue_id); - vlib_cli_output (vm, - " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", - vring->size, vring->last_used_idx, - vring->desc_next, vring->desc_in_use); + vlib_cli_output ( + vm, " qsz %d, last_used_idx %d, desc_next %d, desc_in_use %d", + vring->queue_size, vring->last_used_idx, vring->desc_next, + vring->desc_in_use); if (vif->is_packed) { vlib_cli_output (vm, @@ -571,11 +607,6 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); } - 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 (show_descr) { vlib_cli_output (vm, "\n descriptor table:\n"); @@ -583,11 +614,12 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " id addr len flags next/id user_addr\n"); vlib_cli_output (vm, " ===== ================== ===== ====== ======== ==================\n"); - for (j = 0; j < vring->size; j++) + for (j = 0; j < vring->queue_size; j++) { if (vif->is_packed) { - vring_packed_desc_t *desc = &vring->packed_desc[j]; + vnet_virtio_vring_packed_desc_t *desc = + &vring->packed_desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -596,7 +628,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } else { - vring_desc_t *desc = &vring->desc[j]; + vnet_virtio_vring_desc_t *desc = &vring->desc[j]; vlib_cli_output (vm, " %-5d 0x%016lx %-5d 0x%04x %-8d 0x%016lx\n", j, desc->addr, @@ -606,7 +638,6 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } } } - } } |