X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdevices%2Fvirtio%2Fvhost-user.c;h=c78204065388a69d839302b26a89a8c331f81cb5;hb=352ecd95c9cef74e1726f750dae86c1f97999275;hp=231889342e83d95f99fe371aece5e1fa7a00533f;hpb=f3b53643e87e7521c57cccc157385d2fa4bd0d80;p=vpp.git diff --git a/src/vnet/devices/virtio/vhost-user.c b/src/vnet/devices/virtio/vhost-user.c index 231889342e8..c7820406538 100644 --- a/src/vnet/devices/virtio/vhost-user.c +++ b/src/vnet/devices/virtio/vhost-user.c @@ -49,14 +49,14 @@ */ -#define VHOST_USER_DEBUG_SOCKET 0 #define VHOST_DEBUG_VQ 0 -#if VHOST_USER_DEBUG_SOCKET == 1 -#define DBG_SOCK(args...) clib_warning(args); -#else -#define DBG_SOCK(args...) -#endif +#define DBG_SOCK(args...) \ + { \ + vhost_user_main_t *_vum = &vhost_user_main; \ + if (_vum->debug) \ + clib_warning(args); \ + }; #if VHOST_DEBUG_VQ == 1 #define DBG_VQ(args...) clib_warning(args); @@ -86,10 +86,20 @@ * The value 64 was obtained by testing (48 and 128 were not as good). */ #define VHOST_USER_RX_COPY_THRESHOLD 64 +/* + * On the transmit side, we keep processing the buffers from vlib in the while + * loop and prepare the copy order to be executed later. However, the static + * array which we keep the copy order is limited to VHOST_USER_COPY_ARRAY_N + * entries. In order to not corrupt memory, we have to do the copy when the + * static array reaches the copy threshold. We subtract 40 in case the code + * goes into the inner loop for a maximum of 64k frames which may require + * more array entries. + */ +#define VHOST_USER_TX_COPY_THRESHOLD (VHOST_USER_COPY_ARRAY_N - 40) #define UNIX_GET_FD(unixfd_idx) \ (unixfd_idx != ~0) ? \ - pool_elt_at_index (unix_main.file_pool, \ + pool_elt_at_index (file_main.file_pool, \ unixfd_idx)->file_descriptor : -1; #define foreach_virtio_trace_flags \ @@ -477,20 +487,18 @@ vhost_user_set_interrupt_pending (vhost_user_intf_t * vui, u32 ifq) } static clib_error_t * -vhost_user_callfd_read_ready (unix_file_t * uf) +vhost_user_callfd_read_ready (clib_file_t * uf) { __attribute__ ((unused)) int n; u8 buff[8]; n = read (uf->file_descriptor, ((char *) &buff), 8); - DBG_SOCK ("if %d CALL queue %d", uf->private_data >> 8, - uf->private_data & 0xff); return 0; } static clib_error_t * -vhost_user_kickfd_read_ready (unix_file_t * uf) +vhost_user_kickfd_read_ready (clib_file_t * uf) { __attribute__ ((unused)) int n; u8 buff[8]; @@ -571,16 +579,16 @@ vhost_user_vring_close (vhost_user_intf_t * vui, u32 qid) vhost_user_vring_t *vring = &vui->vrings[qid]; if (vring->kickfd_idx != ~0) { - unix_file_t *uf = pool_elt_at_index (unix_main.file_pool, + clib_file_t *uf = pool_elt_at_index (file_main.file_pool, vring->kickfd_idx); - unix_file_del (&unix_main, uf); + clib_file_del (&file_main, uf); vring->kickfd_idx = ~0; } if (vring->callfd_idx != ~0) { - unix_file_t *uf = pool_elt_at_index (unix_main.file_pool, + clib_file_t *uf = pool_elt_at_index (file_main.file_pool, vring->callfd_idx); - unix_file_del (&unix_main, uf); + clib_file_del (&file_main, uf); vring->callfd_idx = ~0; } if (vring->errfd != -1) @@ -599,10 +607,10 @@ vhost_user_if_disconnect (vhost_user_intf_t * vui) vnet_hw_interface_set_flags (vnm, vui->hw_if_index, 0); - if (vui->unix_file_index != ~0) + if (vui->clib_file_index != ~0) { - unix_file_del (&unix_main, unix_main.file_pool + vui->unix_file_index); - vui->unix_file_index = ~0; + clib_file_del (&file_main, file_main.file_pool + vui->clib_file_index); + vui->clib_file_index = ~0; } vui->is_up = 0; @@ -656,7 +664,7 @@ vhost_user_log_dirty_pages (vhost_user_intf_t * vui, u64 addr, u64 len) } static clib_error_t * -vhost_user_socket_read (unix_file_t * uf) +vhost_user_socket_read (clib_file_t * uf) { int n, i; int fd, number_of_fds = 0; @@ -668,7 +676,7 @@ vhost_user_socket_read (unix_file_t * uf) vhost_user_intf_t *vui; struct cmsghdr *cmsg; u8 q; - unix_file_t template = { 0 }; + clib_file_t template = { 0 }; vnet_main_t *vnm = vnet_get_main (); vui = pool_elt_at_index (vum->vhost_user_interfaces, uf->private_data); @@ -844,8 +852,9 @@ vhost_user_socket_read (unix_file_t * uf) } vui->region_mmap_addr[i] += vui->regions[i].mmap_offset; vui->region_mmap_fd[i] = fds[i]; + + vui->nregions++; } - vui->nregions = msg.memory.nregions; break; case VHOST_USER_SET_VRING_NUM: @@ -856,7 +865,7 @@ vhost_user_socket_read (unix_file_t * uf) (msg.state.num == 0) || /* it cannot be zero */ ((msg.state.num - 1) & msg.state.num)) /* must be power of 2 */ goto close_socket; - vui->vrings[msg.state.index].qsz = msg.state.num; + vui->vrings[msg.state.index].qsz_mask = msg.state.num - 1; break; case VHOST_USER_SET_VRING_ADDR: @@ -921,7 +930,7 @@ vhost_user_socket_read (unix_file_t * uf) break; case VHOST_USER_SET_VRING_CALL: - DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_CALL u64 %d", + DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_CALL %d", vui->hw_if_index, msg.u64); q = (u8) (msg.u64 & 0xFF); @@ -929,13 +938,13 @@ vhost_user_socket_read (unix_file_t * uf) /* if there is old fd, delete and close it */ if (vui->vrings[q].callfd_idx != ~0) { - unix_file_t *uf = pool_elt_at_index (unix_main.file_pool, + clib_file_t *uf = pool_elt_at_index (file_main.file_pool, vui->vrings[q].callfd_idx); - unix_file_del (&unix_main, uf); + clib_file_del (&file_main, uf); vui->vrings[q].callfd_idx = ~0; } - if (!(msg.u64 & 0x100)) + if (!(msg.u64 & VHOST_USER_VRING_NOFD_MASK)) { if (number_of_fds != 1) { @@ -947,27 +956,27 @@ vhost_user_socket_read (unix_file_t * uf) template.file_descriptor = fds[0]; template.private_data = ((vui - vhost_user_main.vhost_user_interfaces) << 8) + q; - vui->vrings[q].callfd_idx = unix_file_add (&unix_main, &template); + vui->vrings[q].callfd_idx = clib_file_add (&file_main, &template); } else vui->vrings[q].callfd_idx = ~0; break; case VHOST_USER_SET_VRING_KICK: - DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_KICK u64 %d", + DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_KICK %d", vui->hw_if_index, msg.u64); q = (u8) (msg.u64 & 0xFF); if (vui->vrings[q].kickfd_idx != ~0) { - unix_file_t *uf = pool_elt_at_index (unix_main.file_pool, + clib_file_t *uf = pool_elt_at_index (file_main.file_pool, vui->vrings[q].kickfd_idx); - unix_file_del (&unix_main, uf); + clib_file_del (&file_main, uf); vui->vrings[q].kickfd_idx = ~0; } - if (!(msg.u64 & 0x100)) + if (!(msg.u64 & VHOST_USER_VRING_NOFD_MASK)) { if (number_of_fds != 1) { @@ -980,7 +989,7 @@ vhost_user_socket_read (unix_file_t * uf) template.private_data = (((uword) (vui - vhost_user_main.vhost_user_interfaces)) << 8) + q; - vui->vrings[q].kickfd_idx = unix_file_add (&unix_main, &template); + vui->vrings[q].kickfd_idx = clib_file_add (&file_main, &template); } else { @@ -992,7 +1001,7 @@ vhost_user_socket_read (unix_file_t * uf) break; case VHOST_USER_SET_VRING_ERR: - DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_ERR u64 %d", + DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_ERR %d", vui->hw_if_index, msg.u64); q = (u8) (msg.u64 & 0xFF); @@ -1000,7 +1009,7 @@ vhost_user_socket_read (unix_file_t * uf) if (vui->vrings[q].errfd != -1) close (vui->vrings[q].errfd); - if (!(msg.u64 & 0x100)) + if (!(msg.u64 & VHOST_USER_VRING_NOFD_MASK)) { if (number_of_fds != 1) goto close_socket; @@ -1020,9 +1029,6 @@ vhost_user_socket_read (unix_file_t * uf) break; case VHOST_USER_GET_VRING_BASE: - DBG_SOCK ("if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d", - vui->hw_if_index, msg.state.index, msg.state.num); - if (msg.state.index >= VHOST_VRING_MAX_N) { DBG_SOCK ("invalid vring index VHOST_USER_GET_VRING_BASE:" @@ -1040,6 +1046,8 @@ vhost_user_socket_read (unix_file_t * uf) /* Spec says: Client must [...] stop ring upon receiving VHOST_USER_GET_VRING_BASE. */ vhost_user_vring_close (vui, msg.state.index); + DBG_SOCK ("if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d", + vui->hw_if_index, msg.state.index, msg.state.num); break; case VHOST_USER_NONE: @@ -1101,28 +1109,30 @@ vhost_user_socket_read (unix_file_t * uf) break; case VHOST_USER_GET_PROTOCOL_FEATURES: - DBG_SOCK ("if %d msg VHOST_USER_GET_PROTOCOL_FEATURES", - vui->hw_if_index); - msg.flags |= 4; msg.u64 = (1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD) | (1 << VHOST_USER_PROTOCOL_F_MQ); msg.size = sizeof (msg.u64); + DBG_SOCK + ("if %d msg VHOST_USER_GET_PROTOCOL_FEATURES - reply 0x%016llx", + vui->hw_if_index, msg.u64); break; case VHOST_USER_SET_PROTOCOL_FEATURES: - DBG_SOCK ("if %d msg VHOST_USER_SET_PROTOCOL_FEATURES features 0x%lx", - vui->hw_if_index, msg.u64); + DBG_SOCK + ("if %d msg VHOST_USER_SET_PROTOCOL_FEATURES features 0x%016llx", + vui->hw_if_index, msg.u64); vui->protocol_features = msg.u64; break; case VHOST_USER_GET_QUEUE_NUM: - DBG_SOCK ("if %d msg VHOST_USER_GET_QUEUE_NUM", vui->hw_if_index); msg.flags |= 4; msg.u64 = VHOST_VRING_MAX_N; msg.size = sizeof (msg.u64); + DBG_SOCK ("if %d msg VHOST_USER_GET_QUEUE_NUM - reply %d", + vui->hw_if_index, msg.u64); break; case VHOST_USER_SET_VRING_ENABLE: @@ -1169,7 +1179,7 @@ close_socket: } static clib_error_t * -vhost_user_socket_error (unix_file_t * uf) +vhost_user_socket_error (clib_file_t * uf) { vlib_main_t *vm = vlib_get_main (); vhost_user_main_t *vum = &vhost_user_main; @@ -1185,11 +1195,11 @@ vhost_user_socket_error (unix_file_t * uf) } static clib_error_t * -vhost_user_socksvr_accept_ready (unix_file_t * uf) +vhost_user_socksvr_accept_ready (clib_file_t * uf) { int client_fd, client_len; struct sockaddr_un client; - unix_file_t template = { 0 }; + clib_file_t template = { 0 }; vhost_user_main_t *vum = &vhost_user_main; vhost_user_intf_t *vui; @@ -1208,7 +1218,7 @@ vhost_user_socksvr_accept_ready (unix_file_t * uf) template.error_function = vhost_user_socket_error; template.file_descriptor = client_fd; template.private_data = vui - vhost_user_main.vhost_user_interfaces; - vui->unix_file_index = unix_file_add (&unix_main, &template); + vui->clib_file_index = clib_file_add (&file_main, &template); return 0; } @@ -1258,7 +1268,7 @@ format_vhost_trace (u8 * s, va_list * va) vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, vui->sw_if_index); - uword indent = format_get_indent (s); + u32 indent = format_get_indent (s); s = format (s, "%U %U queue %d\n", format_white_space, indent, format_vnet_sw_interface_name, vnm, sw, t->qid); @@ -1289,9 +1299,8 @@ vhost_user_rx_trace (vhost_trace_t * t, vlib_buffer_t * b, vhost_user_vring_t * txvq) { vhost_user_main_t *vum = &vhost_user_main; - u32 qsz_mask = txvq->qsz - 1; u32 last_avail_idx = txvq->last_avail_idx; - u32 desc_current = txvq->avail->ring[last_avail_idx & qsz_mask]; + u32 desc_current = txvq->avail->ring[last_avail_idx & txvq->qsz_mask]; vring_desc_t *hdr_desc = 0; virtio_net_hdr_mrg_rxbuf_t *hdr; u32 hint = 0; @@ -1410,19 +1419,19 @@ vhost_user_rx_discard_packet (vlib_main_t * vm, */ u32 discarded_packets = 0; u32 avail_idx = txvq->avail->idx; - u16 qsz_mask = txvq->qsz - 1; while (discarded_packets != discard_max) { if (avail_idx == txvq->last_avail_idx) goto out; u16 desc_chain_head = - txvq->avail->ring[txvq->last_avail_idx & qsz_mask]; + txvq->avail->ring[txvq->last_avail_idx & txvq->qsz_mask]; txvq->last_avail_idx++; - txvq->used->ring[txvq->last_used_idx & qsz_mask].id = desc_chain_head; - txvq->used->ring[txvq->last_used_idx & qsz_mask].len = 0; + txvq->used->ring[txvq->last_used_idx & txvq->qsz_mask].id = + desc_chain_head; + txvq->used->ring[txvq->last_used_idx & txvq->qsz_mask].len = 0; vhost_user_log_dirty_ring (vui, txvq, - ring[txvq->last_used_idx & qsz_mask]); + ring[txvq->last_used_idx & txvq->qsz_mask]); txvq->last_used_idx++; discarded_packets++; } @@ -1470,7 +1479,6 @@ vhost_user_if_input (vlib_main_t * vm, u32 n_left_to_next, *to_next; u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; u32 n_trace = vlib_get_trace_count (vm, node); - u16 qsz_mask; u32 map_hint = 0; u16 thread_index = vlib_get_thread_index (); u16 copy_len = 0; @@ -1530,7 +1538,7 @@ vhost_user_if_input (vlib_main_t * vm, return 0; } - if (PREDICT_FALSE (n_left == txvq->qsz)) + if (PREDICT_FALSE (n_left == (txvq->qsz_mask + 1))) { /* * Informational error logging when VPP is not @@ -1540,8 +1548,6 @@ vhost_user_if_input (vlib_main_t * vm, VHOST_USER_INPUT_FUNC_ERROR_FULL_RX_QUEUE, 1); } - qsz_mask = txvq->qsz - 1; - if (n_left > VLIB_FRAME_SIZE) n_left = VLIB_FRAME_SIZE; @@ -1550,8 +1556,10 @@ vhost_user_if_input (vlib_main_t * vm, * per packet. In case packets are bigger, we will just yeld at some point * in the loop and come back later. This is not an issue as for big packet, * processing cost really comes from the memory copy. + * The assumption is that big packets will fit in 40 buffers. */ - if (PREDICT_FALSE (vum->cpus[thread_index].rx_buffers_len < n_left + 1)) + if (PREDICT_FALSE (vum->cpus[thread_index].rx_buffers_len < n_left + 1 || + vum->cpus[thread_index].rx_buffers_len < 40)) { u32 curr_len = vum->cpus[thread_index].rx_buffers_len; vum->cpus[thread_index].rx_buffers_len += @@ -1606,7 +1614,8 @@ vhost_user_if_input (vlib_main_t * vm, break; } - desc_current = txvq->avail->ring[txvq->last_avail_idx & qsz_mask]; + desc_current = + txvq->avail->ring[txvq->last_avail_idx & txvq->qsz_mask]; vum->cpus[thread_index].rx_buffers_len--; bi_current = (vum->cpus[thread_index].rx_buffers) [vum->cpus[thread_index].rx_buffers_len]; @@ -1622,10 +1631,12 @@ vhost_user_if_input (vlib_main_t * vm, rx_buffers_len - 1], LOAD); /* Just preset the used descriptor id and length for later */ - txvq->used->ring[txvq->last_used_idx & qsz_mask].id = desc_current; - txvq->used->ring[txvq->last_used_idx & qsz_mask].len = 0; + txvq->used->ring[txvq->last_used_idx & txvq->qsz_mask].id = + desc_current; + txvq->used->ring[txvq->last_used_idx & txvq->qsz_mask].len = 0; vhost_user_log_dirty_ring (vui, txvq, - ring[txvq->last_used_idx & qsz_mask]); + ring[txvq->last_used_idx & + txvq->qsz_mask]); /* The buffer should already be initialized */ b_head->total_length_not_including_first_buffer = 0; @@ -1890,9 +1901,8 @@ vhost_user_tx_trace (vhost_trace_t * t, vlib_buffer_t * b, vhost_user_vring_t * rxvq) { vhost_user_main_t *vum = &vhost_user_main; - u32 qsz_mask = rxvq->qsz - 1; u32 last_avail_idx = rxvq->last_avail_idx; - u32 desc_current = rxvq->avail->ring[last_avail_idx & qsz_mask]; + u32 desc_current = rxvq->avail->ring[last_avail_idx & rxvq->qsz_mask]; vring_desc_t *hdr_desc = 0; u32 hint = 0; @@ -1980,7 +1990,6 @@ vhost_user_tx (vlib_main_t * vm, pool_elt_at_index (vum->vhost_user_interfaces, rd->dev_instance); u32 qid = ~0; vhost_user_vring_t *rxvq; - u16 qsz_mask; u8 error; u32 thread_index = vlib_get_thread_index (); u32 map_hint = 0; @@ -2002,13 +2011,11 @@ vhost_user_tx (vlib_main_t * vm, qid = VHOST_VRING_IDX_RX (*vec_elt_at_index - (vui->per_cpu_tx_qid, vlib_get_thread_index ())); + (vui->per_cpu_tx_qid, thread_index)); rxvq = &vui->vrings[qid]; if (PREDICT_FALSE (vui->use_tx_spinlock)) vhost_user_vring_lock (vui, qid); - qsz_mask = rxvq->qsz - 1; /* qsz is always power of 2 */ - retry: error = VHOST_USER_TX_FUNC_ERROR_NONE; tx_headers_len = 0; @@ -2044,7 +2051,7 @@ retry: desc_table = rxvq->desc; desc_head = desc_index = - rxvq->avail->ring[rxvq->last_avail_idx & qsz_mask]; + rxvq->avail->ring[rxvq->last_avail_idx & rxvq->qsz_mask]; /* Go deeper in case of indirect descriptor * I don't know of any driver providing indirect for RX. */ @@ -2109,13 +2116,13 @@ retry: &vum->cpus[thread_index].tx_headers[tx_headers_len - 1]; //Move from available to used buffer - rxvq->used->ring[rxvq->last_used_idx & qsz_mask].id = + rxvq->used->ring[rxvq->last_used_idx & rxvq->qsz_mask].id = desc_head; - rxvq->used->ring[rxvq->last_used_idx & qsz_mask].len = + rxvq->used->ring[rxvq->last_used_idx & rxvq->qsz_mask].len = desc_len; vhost_user_log_dirty_ring (vui, rxvq, ring[rxvq->last_used_idx & - qsz_mask]); + rxvq->qsz_mask]); rxvq->last_avail_idx++; rxvq->last_used_idx++; @@ -2134,7 +2141,7 @@ retry: desc_table = rxvq->desc; desc_head = desc_index = - rxvq->avail->ring[rxvq->last_avail_idx & qsz_mask]; + rxvq->avail->ring[rxvq->last_avail_idx & rxvq->qsz_mask]; if (PREDICT_FALSE (rxvq->desc[desc_head].flags & VIRTQ_DESC_F_INDIRECT)) { @@ -2202,10 +2209,10 @@ retry: } //Move from available to used ring - rxvq->used->ring[rxvq->last_used_idx & qsz_mask].id = desc_head; - rxvq->used->ring[rxvq->last_used_idx & qsz_mask].len = desc_len; + rxvq->used->ring[rxvq->last_used_idx & rxvq->qsz_mask].id = desc_head; + rxvq->used->ring[rxvq->last_used_idx & rxvq->qsz_mask].len = desc_len; vhost_user_log_dirty_ring (vui, rxvq, - ring[rxvq->last_used_idx & qsz_mask]); + ring[rxvq->last_used_idx & rxvq->qsz_mask]); rxvq->last_avail_idx++; rxvq->last_used_idx++; @@ -2216,6 +2223,27 @@ retry: } n_left--; //At the end for error counting when 'goto done' is invoked + + /* + * Do the copy periodically to prevent + * vum->cpus[thread_index].copy array overflow and corrupt memory + */ + if (PREDICT_FALSE (copy_len >= VHOST_USER_TX_COPY_THRESHOLD)) + { + if (PREDICT_FALSE + (vhost_user_tx_copy (vui, vum->cpus[thread_index].copy, + copy_len, &map_hint))) + { + vlib_error_count (vm, node->node_index, + VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL, 1); + } + copy_len = 0; + + /* give buffers back to driver */ + CLIB_MEMORY_BARRIER (); + rxvq->used->idx = rxvq->last_used_idx; + vhost_user_log_dirty_ring (vui, rxvq, idx); + } buffers++; } @@ -2270,7 +2298,7 @@ done3: vlib_increment_simple_counter (vnet_main.interface_main.sw_if_counters + VNET_INTERFACE_COUNTER_DROP, - vlib_get_thread_index (), vui->sw_if_index, n_left); + thread_index, vui->sw_if_index, n_left); } vlib_buffer_free (vm, vlib_frame_args (frame), frame->n_vectors); @@ -2388,6 +2416,11 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, if ((mode == VNET_HW_INTERFACE_RX_MODE_INTERRUPT) || (mode == VNET_HW_INTERFACE_RX_MODE_ADAPTIVE)) { + if (txvq->kickfd_idx == ~0) + { + // We cannot support interrupt mode if the driver opts out + return clib_error_return (0, "Driver does not support interrupt"); + } if (txvq->mode == VNET_HW_INTERFACE_RX_MODE_POLLING) { vum->ifq_count++; @@ -2444,7 +2477,7 @@ vhost_user_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, vui->admin_up = is_up; - if (is_up) + if (is_up && vui->is_up) vnet_hw_interface_set_flags (vnm, vui->hw_if_index, VNET_HW_INTERFACE_FLAG_LINK_UP); @@ -2476,7 +2509,7 @@ vhost_user_process (vlib_main_t * vm, vhost_user_intf_t *vui; struct sockaddr_un sun; int sockfd; - unix_file_t template = { 0 }; + clib_file_t template = { 0 }; f64 timeout = 3153600000.0 /* 100 years */ ; uword *event_data = 0; @@ -2497,7 +2530,7 @@ vhost_user_process (vlib_main_t * vm, pool_foreach (vui, vum->vhost_user_interfaces, { if (vui->unix_server_index == ~0) { //Nothing to do for server sockets - if (vui->unix_file_index == ~0) + if (vui->clib_file_index == ~0) { if ((sockfd < 0) && ((sockfd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)) @@ -2535,7 +2568,7 @@ vhost_user_process (vlib_main_t * vm, template.file_descriptor = sockfd; template.private_data = vui - vhost_user_main.vhost_user_interfaces; - vui->unix_file_index = unix_file_add (&unix_main, &template); + vui->clib_file_index = clib_file_add (&file_main, &template); /* This sockfd is considered consumed */ sockfd = -1; @@ -2550,7 +2583,7 @@ vhost_user_process (vlib_main_t * vm, /* check if socket is alive */ int error = 0; socklen_t len = sizeof (error); - int fd = UNIX_GET_FD(vui->unix_file_index); + int fd = UNIX_GET_FD(vui->clib_file_index); int retval = getsockopt (fd, SOL_SOCKET, SO_ERROR, &error, &len); @@ -2597,9 +2630,9 @@ vhost_user_term_if (vhost_user_intf_t * vui) if (vui->unix_server_index != ~0) { //Close server socket - unix_file_t *uf = pool_elt_at_index (unix_main.file_pool, + clib_file_t *uf = pool_elt_at_index (file_main.file_pool, vui->unix_server_index); - unix_file_del (&unix_main, uf); + clib_file_del (&file_main, uf); vui->unix_server_index = ~0; unlink (vui->sock_filename); } @@ -2781,11 +2814,11 @@ vhost_user_vui_init (vnet_main_t * vnm, sw = vnet_get_hw_sw_interface (vnm, vui->hw_if_index); if (server_sock_fd != -1) { - unix_file_t template = { 0 }; + clib_file_t template = { 0 }; template.read_function = vhost_user_socksvr_accept_ready; template.file_descriptor = server_sock_fd; template.private_data = vui - vum->vhost_user_interfaces; //hw index - vui->unix_server_index = unix_file_add (&unix_main, &template); + vui->unix_server_index = clib_file_add (&file_main, &template); } else { @@ -2798,7 +2831,7 @@ vhost_user_vui_init (vnet_main_t * vnm, vui->sock_errno = 0; vui->is_up = 0; vui->feature_mask = feature_mask; - vui->unix_file_index = ~0; + vui->clib_file_index = ~0; vui->log_base_addr = 0; vui->if_index = vui - vum->vhost_user_interfaces; mhash_set_mem (&vum->if_index_by_sock_name, vui->sock_filename, @@ -3264,7 +3297,8 @@ show_vhost_user_command_fn (vlib_main_t * vm, vlib_cli_output (vm, " qsz %d last_avail_idx %d last_used_idx %d\n", - vui->vrings[q].qsz, vui->vrings[q].last_avail_idx, + vui->vrings[q].qsz_mask + 1, + vui->vrings[q].last_avail_idx, vui->vrings[q].last_used_idx); if (vui->vrings[q].avail && vui->vrings[q].used) @@ -3287,7 +3321,7 @@ show_vhost_user_command_fn (vlib_main_t * vm, " id addr len flags next user_addr\n"); vlib_cli_output (vm, " ===== ================== ===== ====== ===== ==================\n"); - for (j = 0; j < vui->vrings[q].qsz; j++) + for (j = 0; j < vui->vrings[q].qsz_mask + 1; j++) { u32 mem_hint = 0; vlib_cli_output (vm, @@ -3533,6 +3567,64 @@ VLIB_CLI_COMMAND (show_vhost_user_command, static) = { }; /* *INDENT-ON* */ +clib_error_t * +debug_vhost_user_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = NULL; + vhost_user_main_t *vum = &vhost_user_main; + u8 onoff = 0; + u8 input_found = 0; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, "missing argument"); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (input_found) + { + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + goto done; + } + + if (unformat (line_input, "on")) + { + input_found = 1; + onoff = 1; + } + else if (unformat (line_input, "off")) + { + input_found = 1; + onoff = 0; + } + else + { + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + goto done; + } + } + + vum->debug = onoff; + +done: + unformat_free (line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (debug_vhost_user_command, static) = { + .path = "debug vhost-user", + .short_help = "debug vhost-user ", + .function = debug_vhost_user_command_fn, +}; +/* *INDENT-ON* */ + static clib_error_t * vhost_user_config (vlib_main_t * vm, unformat_input_t * input) {