summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChangqian Wang <changqwa@cisco.com>2019-10-18 17:13:13 +0800
committerAndrew Yourtchenko <ayourtch@gmail.com>2019-10-31 12:17:09 +0000
commit709375e7553fe24fea3b89f5eacf9081cfea0247 (patch)
tree2456ac8a5d5eb135c8df93199f13dad0dfd298f8
parentf3ecd4c02938145cd5d072d47df0750a518e7581 (diff)
memif: memif buffer leaks during disconnecting zero copy interface.
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 (cherry picked from commit 00b2d74d1f58b9357e8d955ad7410fb608490904)
-rw-r--r--src/plugins/memif/memif.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/plugins/memif/memif.c b/src/plugins/memif/memif.c
index c2df8d3b12e..05a7f83b3b1 100644
--- a/src/plugins/memif/memif.c
+++ b/src/plugins/memif/memif.c
@@ -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);