From b192feba004e7a52b57ff9f68246b1c94e8b667b Mon Sep 17 00:00:00 2001 From: Juraj Sloboda Date: Mon, 1 Oct 2018 12:42:07 +0200 Subject: [PATCH] vhost-user: Interface state updates Fix inconsistencies between admin and link interface states Admin down should imply link down: link_up = admin_up && link_ready Change-Id: I4d668d82d035b5d2ae508727f34f1722a0c3e677 Signed-off-by: Juraj Sloboda --- src/vnet/devices/virtio/vhost_user.c | 23 ++++++++++++----------- src/vnet/devices/virtio/vhost_user.h | 2 +- src/vnet/devices/virtio/vhost_user_inline.h | 6 ++++++ src/vnet/devices/virtio/vhost_user_output.c | 14 ++++++++++---- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/vnet/devices/virtio/vhost_user.c b/src/vnet/devices/virtio/vhost_user.c index 863cebe0edf..f7730c747b8 100644 --- a/src/vnet/devices/virtio/vhost_user.c +++ b/src/vnet/devices/virtio/vhost_user.c @@ -236,15 +236,16 @@ static void vhost_user_update_iface_state (vhost_user_intf_t * vui) { /* if we have pointers to descriptor table, go up */ - int is_up = vhost_user_intf_ready (vui); - if (is_up != vui->is_up) + int is_ready = vhost_user_intf_ready (vui); + if (is_ready != vui->is_ready) { DBG_SOCK ("interface %d %s", vui->sw_if_index, - is_up ? "ready" : "down"); - vnet_hw_interface_set_flags (vnet_get_main (), vui->hw_if_index, - is_up ? VNET_HW_INTERFACE_FLAG_LINK_UP : - 0); - vui->is_up = is_up; + is_ready ? "ready" : "down"); + if (vui->admin_up) + vnet_hw_interface_set_flags (vnet_get_main (), vui->hw_if_index, + is_ready ? VNET_HW_INTERFACE_FLAG_LINK_UP + : 0); + vui->is_ready = is_ready; } vhost_user_rx_thread_placement (); vhost_user_tx_thread_placement (vui); @@ -290,7 +291,7 @@ vhost_user_kickfd_read_ready (clib_file_t * uf) n = read (uf->file_descriptor, ((char *) &buff), 8); DBG_SOCK ("if %d KICK queue %d", uf->private_data >> 8, qid); if (!vui->vrings[qid].started || - (vhost_user_intf_ready (vui) != vui->is_up)) + (vhost_user_intf_ready (vui) != vui->is_ready)) { vlib_worker_thread_barrier_sync (vlib_get_main ()); vui->vrings[qid].started = 1; @@ -364,7 +365,7 @@ vhost_user_if_disconnect (vhost_user_intf_t * vui) vui->clib_file_index = ~0; } - vui->is_up = 0; + vui->is_ready = 0; for (q = 0; q < VHOST_VRING_MAX_N; q++) vhost_user_vring_close (vui, q); @@ -505,7 +506,7 @@ vhost_user_socket_read (clib_file_t * uf) ASSERT (vui->virtio_net_hdr_sz < VLIB_BUFFER_PRE_DATA_SIZE); vnet_hw_interface_set_flags (vnm, vui->hw_if_index, 0); - vui->is_up = 0; + vui->is_ready = 0; /*for (q = 0; q < VHOST_VRING_MAX_N; q++) vhost_user_vring_close(&vui->vrings[q]); */ @@ -1395,7 +1396,7 @@ vhost_user_vui_init (vnet_main_t * vnm, strncpy (vui->sock_filename, sock_filename, ARRAY_LEN (vui->sock_filename) - 1); vui->sock_errno = 0; - vui->is_up = 0; + vui->is_ready = 0; vui->feature_mask = feature_mask; vui->clib_file_index = ~0; vui->log_base_addr = 0; diff --git a/src/vnet/devices/virtio/vhost_user.h b/src/vnet/devices/virtio/vhost_user.h index ff0669598c9..5bc36082a63 100644 --- a/src/vnet/devices/virtio/vhost_user.h +++ b/src/vnet/devices/virtio/vhost_user.h @@ -253,7 +253,7 @@ typedef struct typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); - u32 is_up; + u32 is_ready; u32 admin_up; u32 unix_server_index; u32 clib_file_index; diff --git a/src/vnet/devices/virtio/vhost_user_inline.h b/src/vnet/devices/virtio/vhost_user_inline.h index 9f6135165ae..7e988eb9969 100644 --- a/src/vnet/devices/virtio/vhost_user_inline.h +++ b/src/vnet/devices/virtio/vhost_user_inline.h @@ -251,6 +251,12 @@ vhost_user_send_call (vlib_main_t * vm, vhost_user_vring_t * vq) vq->int_deadline = vlib_time_now (vm) + vum->coalesce_time; } +static_always_inline u8 +vui_is_link_up (vhost_user_intf_t * vui) +{ + return vui->admin_up && vui->is_ready; +} + #endif /* diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index 029c0c04cc5..f4d1c2c6a7c 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -248,7 +248,7 @@ VNET_DEVICE_CLASS_TX_FN (vhost_user_device_class) (vlib_main_t * vm, goto done3; } - if (PREDICT_FALSE (!vui->is_up)) + if (PREDICT_FALSE (!vui->is_ready)) { error = VHOST_USER_TX_FUNC_ERROR_NOT_READY; goto done3; @@ -621,11 +621,17 @@ vhost_user_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, vhost_user_main_t *vum = &vhost_user_main; vhost_user_intf_t *vui = pool_elt_at_index (vum->vhost_user_interfaces, hif->dev_instance); - u32 hw_flags = 0; + u8 link_old, link_new; + + link_old = vui_is_link_up (vui); + vui->admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0; - hw_flags = vui->admin_up ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0; - vnet_hw_interface_set_flags (vnm, vui->hw_if_index, hw_flags); + link_new = vui_is_link_up (vui); + + if (link_old != link_new) + vnet_hw_interface_set_flags (vnm, vui->hw_if_index, link_new ? + VNET_HW_INTERFACE_FLAG_LINK_UP : 0); return /* no error */ 0; } -- 2.16.6