From: Mohsin Kazmi Date: Mon, 2 May 2016 12:04:57 +0000 (+0200) Subject: NETMAP: Some fixes X-Git-Tag: v16.06-rc1~46 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=8f15e922f7f32c1beca5baa9a1a7f187ff5bdc4f NETMAP: Some fixes 1) Correct the NIOCRXSYNC macro on receive side from NIOCTXSYNC. 2) Flush the pending messages in the tx rings. Change-Id: I581040d03b1633a3d6fb22fa1fb285bcb7975afb Signed-off-by: Mohsin Kazmi --- diff --git a/vnet/vnet/devices/netmap/device.c b/vnet/vnet/devices/netmap/device.c index 36e17da2a22..dcd04733613 100644 --- a/vnet/vnet/devices/netmap/device.c +++ b/vnet/vnet/devices/netmap/device.c @@ -22,7 +22,8 @@ #include #define foreach_netmap_tx_func_error \ -_(NO_FREE_SLOTS, "no free tx slots") +_(NO_FREE_SLOTS, "no free tx slots") \ +_(PENDING_MSGS, "pending msgs in tx ring") typedef enum { #define _(f,s) NETMAP_TX_ERROR_##f, @@ -92,6 +93,7 @@ netmap_interface_tx (vlib_main_t * vm, netmap_main_t * nm = &netmap_main; u32 * buffers = vlib_frame_args (frame); u32 n_left = frame->n_vectors; + f64 const time_constant = 1e3; vnet_interface_output_runtime_t * rd = (void *) node->runtime_data; netmap_if_t * nif = pool_elt_at_index (nm->interfaces, rd->dev_instance); int cur_ring; @@ -104,21 +106,27 @@ netmap_interface_tx (vlib_main_t * vm, int n_free_slots = nm_ring_space(ring); uint cur = ring->cur; - if (!n_free_slots) - { - cur_ring++; - continue; - } + if (nm_tx_pending(ring)) + { + ioctl(nif->fd, NIOCTXSYNC, NULL); + clib_cpu_time_wait(time_constant); + + if (nm_tx_pending(ring) && !n_free_slots) + { + cur_ring++; + continue; + } + } while (n_left && n_free_slots) { - vlib_buffer_t * b0; + vlib_buffer_t * b0 = 0; u32 bi = buffers[0]; u32 len; u32 offset = 0; buffers++; - struct netmap_slot * slot = &ring->slot[cur]; + struct netmap_slot * slot = &ring->slot[cur]; do { @@ -144,8 +152,8 @@ netmap_interface_tx (vlib_main_t * vm, ioctl(nif->fd, NIOCTXSYNC, NULL); if (n_left) - vlib_error_count (vm, node->node_index, NETMAP_TX_ERROR_NO_FREE_SLOTS, - n_left); + vlib_error_count (vm, node->node_index, + (n_left == frame->n_vectors ? NETMAP_TX_ERROR_PENDING_MSGS : NETMAP_TX_ERROR_NO_FREE_SLOTS), n_left); vlib_buffer_free (vm, vlib_frame_args (frame), frame->n_vectors); return frame->n_vectors; diff --git a/vnet/vnet/devices/netmap/netmap.h b/vnet/vnet/devices/netmap/netmap.h index d9a476b6959..15b14dbb0b7 100644 --- a/vnet/vnet/devices/netmap/netmap.h +++ b/vnet/vnet/devices/netmap/netmap.h @@ -119,6 +119,23 @@ int netmap_delete_if(vlib_main_t * vm, u8 * host_if_name); ( ((char *)(buf) - ((char *)(ring) + (ring)->buf_ofs) ) / \ (ring)->nr_buf_size ) +static inline uint32_t +nm_ring_next(struct netmap_ring *ring, uint32_t i) +{ + return ( unlikely(i + 1 == ring->num_slots) ? 0 : i + 1); +} + + +/* + * Return 1 if we have pending transmissions in the tx ring. + * When everything is complete ring->head = ring->tail + 1 (modulo ring size) + */ +static inline int +nm_tx_pending(struct netmap_ring *ring) +{ + return nm_ring_next(ring, ring->tail) != ring->head; +} + static inline uint32_t nm_ring_space(struct netmap_ring *ring) { diff --git a/vnet/vnet/devices/netmap/node.c b/vnet/vnet/devices/netmap/node.c index f866a282cfb..d4c01411904 100644 --- a/vnet/vnet/devices/netmap/node.c +++ b/vnet/vnet/devices/netmap/node.c @@ -235,7 +235,7 @@ netmap_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, } if (n_rx_packets) - ioctl(nif->fd, NIOCTXSYNC, NULL); + ioctl(nif->fd, NIOCRXSYNC, NULL); vlib_increment_combined_counter (vnet_get_main()->interface_main.combined_sw_if_counters