memif: memif buffer leaks during disconnecting zero copy interface. 29/22829/5
authorChangqian Wang <changqwa@cisco.com>
Fri, 18 Oct 2019 09:13:13 +0000 (17:13 +0800)
committerDamjan Marion <dmarion@me.com>
Wed, 23 Oct 2019 14:28:12 +0000 (14:28 +0000)
code added to free the zero copy interface rx/tx queue buffers during disconnecting.
As ddc9eb4 find the last official solution introduced core in ut. This does not.

Type: fix

Signed-off-by: Changqian Wang <changqwa@cisco.com>
Change-Id: I971ee164e6d4331a85feb9e65d6702d771c86985

src/plugins/memif/memif.c

index c2df8d3..05a7f83 100644 (file)
@@ -65,6 +65,24 @@ memif_queue_intfd_close (memif_queue_t * mq)
     }
 }
 
+static void
+memif_disconnect_free_zc_queue_buffer (memif_queue_t * mq, u8 is_rx)
+{
+  vlib_main_t *vm = vlib_get_main ();
+  u16 ring_size, n_slots, mask, start;
+
+  ring_size = 1 << mq->log2_ring_size;
+  mask = ring_size - 1;
+  n_slots = mq->ring->head - mq->last_tail;
+  start = mq->last_tail & mask;
+  if (is_rx)
+    vlib_buffer_free_from_ring (vm, mq->buffers, start, ring_size, n_slots);
+  else
+    vlib_buffer_free_from_ring_no_next (vm, mq->buffers, start, ring_size,
+                                       n_slots);
+  vec_free (mq->buffers);
+}
+
 void
 memif_disconnect (memif_if_t * mif, clib_error_t * err)
 {
@@ -126,10 +144,28 @@ 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);
+         if (mif->flags & MEMIF_IF_FLAG_ZERO_COPY)
+         {
+           memif_disconnect_free_zc_queue_buffer(mq, 1);
+         }
          mq->ring = 0;
        }
     }
 
+  /* *INDENT-OFF* */
+  vec_foreach_index (i, mif->tx_queues)
+  {
+    mq = vec_elt_at_index (mif->tx_queues, i);
+    if (mq->ring)
+    {
+      if (mif->flags & MEMIF_IF_FLAG_ZERO_COPY)
+      {
+        memif_disconnect_free_zc_queue_buffer(mq, 0);
+      }
+    }
+    mq->ring = 0;
+  }
+
   /* free tx and rx queues */
   vec_foreach (mq, mif->rx_queues)
     memif_queue_intfd_close (mq);