vhost: memory leak upon deleting vhost-user interface
[vpp.git] / src / vnet / devices / virtio / virtio.c
index b8054d1..ee14935 100644 (file)
@@ -33,6 +33,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 +60,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 +74,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 +85,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 +116,20 @@ 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->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 +142,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 +164,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 +189,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,7 +204,7 @@ 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;
 
@@ -222,7 +222,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 +239,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 +285,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 +437,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 +478,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 +492,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 +506,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 +550,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 +564,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 +574,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 +603,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 +610,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 +624,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 +634,6 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type)
                }
            }
        }
-
     }
 
 }