memif: memif buffer leaks during disconnect.
[vpp.git] / src / plugins / memif / memif.c
index 3171ba2..c216a16 100644 (file)
@@ -70,6 +70,7 @@ memif_disconnect (memif_if_t * mif, clib_error_t * err)
 {
   memif_main_t *mm = &memif_main;
   vnet_main_t *vnm = vnet_get_main ();
+  vlib_main_t *vm = vlib_get_main ();
   memif_region_t *mr;
   memif_queue_t *mq;
   int i;
@@ -126,7 +127,19 @@ memif_disconnect (memif_if_t * mif, clib_error_t * err)
            memif_log_warn (mif,
                           "Unable to unassign interface %d, queue %d: rc=%d",
                           mif->hw_if_index, i, rv);
-         mq->ring = 0;
+         if (mif->flags & MEMIF_IF_FLAG_ZERO_COPY)
+            {
+
+              u16 cur_slot,last_slot, start;
+              u16 ring_size = 1 << mq->log2_ring_size;
+              u16 mask = ring_size - 1;
+              cur_slot =  mq->last_tail;
+              last_slot = mq->ring->head - 1 ;
+              start = (mq->last_tail & mask);
+              u16 n_slots = ((last_slot - cur_slot) & mask) + 1;
+              vlib_buffer_free_from_ring(vm,mq->buffers,start,ring_size,n_slots);
+            }
+          mq->ring = 0;
        }
     }
 
@@ -136,7 +149,28 @@ memif_disconnect (memif_if_t * mif, clib_error_t * err)
   vec_free (mif->rx_queues);
 
   vec_foreach (mq, mif->tx_queues)
-    memif_queue_intfd_close (mq);
+    {
+      if (mif->flags & MEMIF_IF_FLAG_ZERO_COPY)
+        {
+          memif_ring_t *ring = mq->ring;
+          u16 cur_slot,last_slot, start;
+          u16 ring_size = 1 << mq->log2_ring_size;
+          u16 mask = ring_size - 1;
+          u16 n_slots = ring->tail - mq->last_tail;
+          cur_slot =  mq->last_tail;
+          last_slot = mq->ring->head;
+          start = (mq->last_tail & mask);
+          if(last_slot > cur_slot)
+             n_slots = n_slots + ((last_slot - cur_slot)) ;
+          else if (last_slot < cur_slot)
+             n_slots = n_slots + (cur_slot - last_slot);
+          vlib_buffer_free_from_ring_no_next (vm, mq->buffers,
+                      start,
+                      ring_size, n_slots);
+        }
+      memif_queue_intfd_close (mq);
+    }
+
   vec_free (mif->tx_queues);
 
   /* free memory regions */
@@ -185,6 +219,7 @@ memif_int_fd_read_ready (clib_file_t * uf)
 clib_error_t *
 memif_connect (memif_if_t * mif)
 {
+  vlib_main_t *vm = vlib_get_main ();
   vnet_main_t *vnm = vnet_get_main ();
   clib_file_t template = { 0 };
   memif_region_t *mr;
@@ -235,6 +270,7 @@ memif_connect (memif_if_t * mif)
   vec_foreach_index (i, mif->rx_queues)
     {
       memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
+      u32 ti;
       int rv;
 
       mq->ring = mif->regions[mq->region].shm + mq->offset;
@@ -254,6 +290,9 @@ memif_connect (memif_if_t * mif)
          memif_file_add (&mq->int_clib_file_index, &template);
        }
       vnet_hw_interface_assign_rx_thread (vnm, mif->hw_if_index, i, ~0);
+      ti = vnet_get_device_input_thread_index (vnm, mif->hw_if_index, i);
+      mq->buffer_pool_index =
+       vlib_buffer_pool_get_default_for_numa (vm, vlib_mains[ti]->numa_node);
       rv = vnet_hw_interface_set_rx_mode (vnm, mif->hw_if_index, i,
                                          VNET_HW_INTERFACE_RX_MODE_DEFAULT);
       if (rv)
@@ -338,7 +377,7 @@ memif_init_regions_and_queues (memif_if_t * mif)
     {
       vlib_buffer_pool_t *bp;
       /* *INDENT-OFF* */
-      vec_foreach (bp, buffer_main.buffer_pools)
+      vec_foreach (bp, vm->buffer_main->buffer_pools)
        {
          vlib_physmem_map_t *pm;
          pm = vlib_physmem_get_map (vm, bp->physmem_map_index);
@@ -1039,7 +1078,7 @@ VLIB_INIT_FUNCTION (memif_init);
 /* *INDENT-OFF* */
 VLIB_PLUGIN_REGISTER () = {
     .version = VPP_BUILD_VER,
-    .description = "Packet Memory Interface (experimental)",
+    .description = "Packet Memory Interface (memif) -- Experimental",
 };
 /* *INDENT-ON* */