vhost-user: Interface state updates 72/15072/2
authorJuraj Sloboda <jsloboda@cisco.com>
Mon, 1 Oct 2018 10:42:07 +0000 (12:42 +0200)
committerOle Trøan <otroan@employees.org>
Tue, 2 Oct 2018 12:21:36 +0000 (12:21 +0000)
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 <jsloboda@cisco.com>
src/vnet/devices/virtio/vhost_user.c
src/vnet/devices/virtio/vhost_user.h
src/vnet/devices/virtio/vhost_user_inline.h
src/vnet/devices/virtio/vhost_user_output.c

index 863cebe..f7730c7 100644 (file)
@@ -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;
index ff06695..5bc3608 100644 (file)
@@ -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;
index 9f61351..7e988eb 100644 (file)
@@ -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
 
 /*
index 029c0c0..f4d1c2c 100644 (file)
@@ -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;
 }