memif: memory leak when deleting memif interface
[vpp.git] / src / plugins / memif / memif.c
index f8c5191..f2575fd 100644 (file)
@@ -231,6 +231,7 @@ memif_int_fd_read_ready (clib_file_t * uf)
 clib_error_t *
 memif_connect (memif_if_t * mif)
 {
+  memif_main_t *mm = &memif_main;
   vlib_main_t *vm = vlib_get_main ();
   vnet_main_t *vnm = vnet_get_main ();
   clib_file_t template = { 0 };
@@ -238,6 +239,7 @@ memif_connect (memif_if_t * mif)
   int i, j;
   u32 n_txqs = 0, n_threads = vlib_get_n_threads ();
   clib_error_t *err = NULL;
+  u8 max_log2_ring_sz = 0;
 
   memif_log_debug (mif, "connect %u", mif->dev_instance);
 
@@ -272,6 +274,7 @@ memif_connect (memif_if_t * mif)
   vec_foreach_index (i, mif->tx_queues)
     {
       memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
+      max_log2_ring_sz = clib_max (max_log2_ring_sz, mq->log2_ring_size);
 
       mq->ring = mif->regions[mq->region].shm + mq->offset;
       if (mq->ring->cookie != MEMIF_COOKIE)
@@ -301,6 +304,8 @@ memif_connect (memif_if_t * mif)
       u32 qi;
       int rv;
 
+      max_log2_ring_sz = clib_max (max_log2_ring_sz, mq->log2_ring_size);
+
       mq->ring = mif->regions[mq->region].shm + mq->offset;
       if (mq->ring->cookie != MEMIF_COOKIE)
        {
@@ -343,6 +348,30 @@ memif_connect (memif_if_t * mif)
     }
   /* *INDENT-ON* */
 
+  if (1 << max_log2_ring_sz > vec_len (mm->per_thread_data[0].desc_data))
+    {
+      memif_per_thread_data_t *ptd;
+      int with_barrier = 1;
+
+      if (vlib_worker_thread_barrier_held ())
+       with_barrier = 0;
+
+      if (with_barrier)
+       vlib_worker_thread_barrier_sync (vm);
+
+      vec_foreach (ptd, mm->per_thread_data)
+       {
+         vec_validate_aligned (ptd->desc_data, pow2_mask (max_log2_ring_sz),
+                               CLIB_CACHE_LINE_BYTES);
+         vec_validate_aligned (ptd->desc_len, pow2_mask (max_log2_ring_sz),
+                               CLIB_CACHE_LINE_BYTES);
+         vec_validate_aligned (ptd->desc_status, pow2_mask (max_log2_ring_sz),
+                               CLIB_CACHE_LINE_BYTES);
+       }
+      if (with_barrier)
+       vlib_worker_thread_barrier_release (vm);
+    }
+
   mif->flags &= ~MEMIF_IF_FLAG_CONNECTING;
   mif->flags |= MEMIF_IF_FLAG_CONNECTED;
 
@@ -844,6 +873,7 @@ memif_delete_if (vlib_main_t * vm, memif_if_t * mif)
        }
     }
 
+  vec_free (mif->local_disc_string);
   clib_memset (mif, 0, sizeof (*mif));
   pool_put (mm->interfaces, mif);
 
@@ -868,12 +898,12 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
   memif_main_t *mm = &memif_main;
   vlib_thread_main_t *tm = vlib_get_thread_main ();
   vnet_main_t *vnm = vnet_get_main ();
+  vnet_eth_interface_registration_t eir = {};
   memif_if_t *mif = 0;
   vnet_sw_interface_t *sw;
   clib_error_t *error = 0;
   int ret = 0;
   uword *p;
-  vnet_hw_interface_t *hw;
   memif_socket_file_t *msf = 0;
   int rv = 0;
 
@@ -983,10 +1013,12 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
          args->hw_addr[0] = 2;
          args->hw_addr[1] = 0xfe;
        }
-      error = ethernet_register_interface (vnm, memif_device_class.index,
-                                          mif->dev_instance, args->hw_addr,
-                                          &mif->hw_if_index,
-                                          memif_eth_flag_change);
+
+      eir.dev_class_index = memif_device_class.index;
+      eir.dev_instance = mif->dev_instance;
+      eir.address = args->hw_addr;
+      eir.cb.flag_change = memif_eth_flag_change;
+      mif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
     }
   else if (mif->mode == MEMIF_INTERFACE_MODE_IP)
     {
@@ -1061,8 +1093,7 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
        mif->flags |= MEMIF_IF_FLAG_ZERO_COPY;
     }
 
-  hw = vnet_get_hw_interface (vnm, mif->hw_if_index);
-  hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE;
+  vnet_hw_if_set_caps (vnm, mif->hw_if_index, VNET_HW_IF_CAP_INT_MODE);
   vnet_hw_if_set_input_node (vnm, mif->hw_if_index, memif_input_node.index);
   mhash_set (&msf->dev_instance_by_id, &mif->id, mif->dev_instance, 0);