From 3978577d2e4affb63d96e15a5f22ba2c6ae955f9 Mon Sep 17 00:00:00 2001
From: Olivier Matz <olivier.matz@6wind.com>
Date: Wed, 17 Jan 2018 14:52:33 +0100
Subject: [PATCH] debug malloc

---
 drivers/net/virtio/Makefile             |   1 +
 drivers/net/virtio/virtio_alloc.c       | 121 ++++++++++++++++++++++++++++++++
 drivers/net/virtio/virtio_alloc.h       |  80 +++++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      |  54 +++++++-------
 drivers/net/virtio/virtio_rxtx.c        |  15 ++--
 drivers/net/virtio/virtio_user_ethdev.c |  11 +--
 drivers/net/virtio/virtqueue.c          |   3 +-
 7 files changed, 248 insertions(+), 37 deletions(-)
 create mode 100644 drivers/net/virtio/virtio_alloc.c
 create mode 100644 drivers/net/virtio/virtio_alloc.h

diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index f2b5d1c33..9e28edb6d 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -57,6 +57,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_pci.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_simple.c
+SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_alloc.c
 
 ifeq ($(CONFIG_RTE_ARCH_X86),y)
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_simple_sse.c
diff --git a/drivers/net/virtio/virtio_alloc.c b/drivers/net/virtio/virtio_alloc.c
new file mode 100644
index 000000000..02d3bfe61
--- /dev/null
+++ b/drivers/net/virtio/virtio_alloc.c
@@ -0,0 +1,121 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/queue.h>
+#include <assert.h>
+
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "virtio_alloc.h"
+
+#define HORDER 16
+#define HSIZE (1UL << HORDER)
+#define HMASK (HSIZE - 1)
+
+LIST_HEAD(debug_alloc_list, debug_alloc);
+static struct debug_alloc_list debug_alloc_list;
+static struct debug_alloc_list debug_alloc_hlist[HSIZE];
+static unsigned int id;
+
+struct debug_alloc {
+	LIST_ENTRY(debug_alloc) next;
+	LIST_ENTRY(debug_alloc) hnext;
+	char *name;
+	const void *ptr;
+	enum debug_malloc_type type;
+	const char *file;
+	unsigned int line;
+	size_t size;
+	unsigned int id;
+};
+
+static unsigned int hash(const void *ptr, enum debug_malloc_type type)
+{
+	unsigned int h;
+
+	h = (uintptr_t)ptr;
+	h = h ^ (h >> 7) ^ (h >> 13) ^ (h >> 27) ^ (unsigned int)type;
+
+	return h & HMASK;
+}
+
+void trace_malloc(const char *name, enum debug_malloc_type type, const void *ptr,
+		size_t size, const char *file,
+		unsigned int line)
+{
+	struct debug_alloc *dbg, *d;
+	unsigned int h;
+
+	assert(ptr != NULL);
+
+	dbg = malloc(sizeof(*dbg));
+	assert(dbg != NULL);
+
+	if (name)
+		dbg->name = strdup(name);
+	else
+		dbg->name = NULL;
+	dbg->ptr = ptr;
+	dbg->type = type;
+	dbg->file = file;
+	dbg->line = line;
+	dbg->size = size;
+	dbg->id = id++;
+
+	XLOG("%s:%d: alloc(%s) -> %p id=%d\n", file, line, name, ptr, dbg->id);
+
+	h = hash(ptr, type);
+
+	LIST_FOREACH(d, &debug_alloc_hlist[h], hnext) {
+		assert(d->ptr != dbg->ptr);
+	}
+
+	LIST_INSERT_HEAD(&debug_alloc_hlist[h], dbg, hnext);
+	LIST_INSERT_HEAD(&debug_alloc_list, dbg, next);
+}
+
+void check_free(enum debug_malloc_type type, const void *ptr,
+		const char *file, unsigned int line)
+{
+	struct debug_alloc *dbg;
+	unsigned int h;
+
+	if (ptr == NULL)
+		return;
+
+	(void)file;
+	(void)line;
+
+	h = hash(ptr, type);
+	LIST_FOREACH(dbg, &debug_alloc_hlist[h], hnext) {
+		if (dbg->ptr == ptr && dbg->type == type)
+			break;
+	}
+
+	assert(dbg != NULL);
+
+	XLOG("%s:%d: free(%p) id=%d\n", file, line, ptr, dbg->id);
+	LIST_REMOVE(dbg, hnext);
+	LIST_REMOVE(dbg, next);
+	free(dbg->name);
+	free(dbg);
+}
+
+void debug_alloc_dump(const char *name)
+{
+	struct debug_alloc *dbg;
+
+	XLOG("DUMP %s ====================================================\n",
+		name);
+
+	LIST_FOREACH(dbg, &debug_alloc_list, next) {
+		XLOG("name=%s ptr=%p type=%d size=%zd id=%d %s:%d\n",
+			dbg->name, dbg->ptr, dbg->type, dbg->size, dbg->id,
+			dbg->file, dbg->line);
+	}
+	XLOG("=====================================\n");
+}
diff --git a/drivers/net/virtio/virtio_alloc.h b/drivers/net/virtio/virtio_alloc.h
new file mode 100644
index 000000000..3ea15ce76
--- /dev/null
+++ b/drivers/net/virtio/virtio_alloc.h
@@ -0,0 +1,80 @@
+#ifndef _VIRTIO_ALLOC_H
+#define _VIRTIO_ALLOC_H
+
+enum debug_malloc_type {
+	RTE_MALLOC,
+	RTE_MEMZONE,
+	RTE_MBUF,
+};
+
+void trace_malloc(const char *name, enum debug_malloc_type type,
+		const void *ptr,
+		size_t size, const char *file,
+		unsigned int line);
+
+void check_free(enum debug_malloc_type type, const void *ptr,
+		const char *file, unsigned int line);
+
+void debug_alloc_dump(const char *name);
+
+#define XLOG(args...) RTE_LOG(INFO, PMD, ## args)
+
+/* rte_malloc */
+
+#define dbg_zmalloc(name, size, align) ({ \
+	void *__p = rte_zmalloc(name, size, align); \
+	if (__p != NULL) \
+		trace_malloc(name, RTE_MALLOC, __p, size, __FILE__, __LINE__); \
+	__p; \
+})
+
+#define dbg_zmalloc_socket(name, size, align, socket) ({ \
+	void *__p = rte_zmalloc_socket(name, size, align, socket); \
+	if (__p != NULL) \
+		trace_malloc(name, RTE_MALLOC, __p, size, __FILE__, __LINE__); \
+	__p; \
+})
+
+#define dbg_free(ptr) do { \
+	check_free(RTE_MALLOC, ptr, __FILE__, __LINE__); \
+	rte_free(ptr); \
+} while(0)
+
+/* rte_memzone */
+
+#define dbg_memzone_reserve_aligned(name, size, socket, flags, align) ({ \
+	const struct rte_memzone *__mz = \
+		rte_memzone_reserve_aligned(name, size, socket, flags, align); \
+	if (__mz) \
+		trace_malloc(name, RTE_MEMZONE, __mz, size, __FILE__, __LINE__); \
+	__mz; \
+})
+
+#define dbg_memzone_free(ptr) do { \
+	check_free(RTE_MEMZONE, ptr, __FILE__, __LINE__); \
+	rte_memzone_free(ptr); \
+} while(0)
+
+/* mbuf: it is incomplete, but enough to track init/uninit */
+
+#define dbg_pktmbuf_alloc(pool) ({ \
+	struct rte_mbuf *__m = rte_pktmbuf_alloc(pool); \
+	if (__m != NULL) \
+		trace_malloc("mbuf", RTE_MBUF, __m, 1, __FILE__, __LINE__); \
+	__m; \
+})
+
+#define dbg_mbuf_raw_alloc(pool) ({ \
+	struct rte_mbuf *__m = rte_mbuf_raw_alloc(pool); \
+	if (__m != NULL) \
+		trace_malloc("mbuf", RTE_MBUF, __m, 1, __FILE__, __LINE__); \
+	__m; \
+})
+
+#define dbg_pktmbuf_free(m) do { \
+	check_free(RTE_MBUF, m, __FILE__, __LINE__); \
+	rte_pktmbuf_free(m); \
+} while(0)
+
+
+#endif
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index a10f437ca..639c9d328 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -61,6 +61,7 @@
 #include "virtio_logs.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
+#include "virtio_alloc.h"
 
 static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
@@ -397,7 +398,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		sz_hdr_mz = PAGE_SIZE;
 	}
 
-	vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,
+	vq = dbg_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,
 				SOCKET_ID_ANY);
 	if (vq == NULL) {
 		PMD_INIT_LOG(ERR, "can not allocate vq");
@@ -417,7 +418,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d",
 		     size, vq->vq_ring_size);
 
-	mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
+	mz = dbg_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
 					 SOCKET_ID_ANY,
 					 0, VIRTIO_PCI_VRING_ALIGN);
 	if (mz == NULL) {
@@ -443,7 +444,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	if (sz_hdr_mz) {
 		snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
 			 dev->data->port_id, vtpci_queue_idx);
-		hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
+		hdr_mz = dbg_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
 						     SOCKET_ID_ANY, 0,
 						     RTE_CACHE_LINE_SIZE);
 		if (hdr_mz == NULL) {
@@ -460,7 +461,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		size_t sz_sw = (RTE_PMD_VIRTIO_RX_MAX_BURST + vq_size) *
 			       sizeof(vq->sw_ring[0]);
 
-		sw_ring = rte_zmalloc_socket("sw_ring", sz_sw,
+		sw_ring = dbg_zmalloc_socket("sw_ring", sz_sw,
 				RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
 		if (!sw_ring) {
 			PMD_INIT_LOG(ERR, "can not allocate RX soft ring");
@@ -535,10 +536,10 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	return 0;
 
 fail_q_alloc:
-	rte_free(sw_ring);
-	rte_memzone_free(hdr_mz);
-	rte_memzone_free(mz);
-	rte_free(vq);
+	dbg_free(sw_ring);
+	dbg_memzone_free(hdr_mz);
+	dbg_memzone_free(mz);
+	dbg_free(vq);
 
 	return ret;
 }
@@ -561,21 +562,21 @@ virtio_free_queues(struct virtio_hw *hw)
 
 		queue_type = virtio_get_queue_type(hw, i);
 		if (queue_type == VTNET_RQ) {
-			rte_free(vq->sw_ring);
-			rte_memzone_free(vq->rxq.mz);
+			dbg_free(vq->sw_ring);
+			dbg_memzone_free(vq->rxq.mz);
 		} else if (queue_type == VTNET_TQ) {
-			rte_memzone_free(vq->txq.mz);
-			rte_memzone_free(vq->txq.virtio_net_hdr_mz);
+			dbg_memzone_free(vq->txq.mz);
+			dbg_memzone_free(vq->txq.virtio_net_hdr_mz);
 		} else {
-			rte_memzone_free(vq->cq.mz);
-			rte_memzone_free(vq->cq.virtio_net_hdr_mz);
+			dbg_memzone_free(vq->cq.mz);
+			dbg_memzone_free(vq->cq.virtio_net_hdr_mz);
 		}
 
-		rte_free(vq);
+		dbg_free(vq);
 		hw->vqs[i] = NULL;
 	}
 
-	rte_free(hw->vqs);
+	dbg_free(hw->vqs);
 	hw->vqs = NULL;
 }
 
@@ -587,7 +588,7 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
 	uint16_t i;
 	int ret;
 
-	hw->vqs = rte_zmalloc(NULL, sizeof(struct virtqueue *) * nr_vq, 0);
+	hw->vqs = dbg_zmalloc(NULL, sizeof(struct virtqueue *) * nr_vq, 0);
 	if (!hw->vqs) {
 		PMD_INIT_LOG(ERR, "failed to allocate vqs");
 		return -ENOMEM;
@@ -623,13 +624,15 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	if (intr_conf->lsc || intr_conf->rxq) {
 		virtio_intr_disable(dev);
 		rte_intr_efd_disable(dev->intr_handle);
-		rte_free(dev->intr_handle->intr_vec);
+		dbg_free(dev->intr_handle->intr_vec);
 		dev->intr_handle->intr_vec = NULL;
 	}
 
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
+
+	debug_alloc_dump("close");
 }
 
 static void
@@ -1356,7 +1359,7 @@ virtio_configure_intr(struct rte_eth_dev *dev)
 
 	if (!dev->intr_handle->intr_vec) {
 		dev->intr_handle->intr_vec =
-			rte_zmalloc("intr_vec",
+			dbg_zmalloc("intr_vec",
 				    hw->max_queue_pairs * sizeof(int), 0);
 		if (!dev->intr_handle->intr_vec) {
 			PMD_INIT_LOG(ERR, "Failed to allocate %u rxq vectors",
@@ -1588,6 +1591,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	int ret;
 
 	RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr_mrg_rxbuf));
+	debug_alloc_dump("start_dev_init");
 
 	eth_dev->dev_ops = &virtio_eth_dev_ops;
 
@@ -1605,7 +1609,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	/* Allocate memory for storing MAC addresses */
-	eth_dev->data->mac_addrs = rte_zmalloc("virtio", VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN, 0);
+	eth_dev->data->mac_addrs = dbg_zmalloc("virtio", VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN, 0);
 	if (eth_dev->data->mac_addrs == NULL) {
 		PMD_INIT_LOG(ERR,
 			"Failed to allocate %d bytes needed to store MAC addresses",
@@ -1633,10 +1637,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 		rte_intr_callback_register(eth_dev->intr_handle,
 			virtio_interrupt_handler, eth_dev);
 
+	debug_alloc_dump("end_dev_init");
 	return 0;
 
 out:
-	rte_free(eth_dev->data->mac_addrs);
+	dbg_free(eth_dev->data->mac_addrs);
 	return ret;
 }
 
@@ -1655,7 +1660,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 	eth_dev->tx_pkt_burst = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 
-	rte_free(eth_dev->data->mac_addrs);
+	dbg_free(eth_dev->data->mac_addrs);
 	eth_dev->data->mac_addrs = NULL;
 
 	/* reset interrupt callback  */
@@ -1667,6 +1672,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 		rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
 
 	PMD_INIT_LOG(DEBUG, "dev_uninit completed");
+	debug_alloc_dump("end_dev_uninit");
 
 	return 0;
 }
@@ -1909,7 +1915,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 
 		PMD_INIT_LOG(DEBUG, "rx_queues[%d]=%p", i, rxvq);
 		while ((buf = virtqueue_detatch_unused(rxvq->vq)) != NULL) {
-			rte_pktmbuf_free(buf);
+			dbg_pktmbuf_free(buf);
 			mbuf_num++;
 		}
 
@@ -1929,7 +1935,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 
 		mbuf_num = 0;
 		while ((buf = virtqueue_detatch_unused(txvq->vq)) != NULL) {
-			rte_pktmbuf_free(buf);
+			dbg_pktmbuf_free(buf);
 			mbuf_num++;
 		}
 
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 83cc22aaf..e61528410 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -59,6 +59,7 @@
 #include "virtio_pci.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
+#include "virtio_alloc.h"
 
 #ifdef RTE_LIBRTE_VIRTIO_DEBUG_DUMP
 #define VIRTIO_DUMP_PACKET(m, len) rte_pktmbuf_dump(stdout, m, len)
@@ -169,7 +170,7 @@ virtio_xmit_cleanup(struct virtqueue *vq, uint16_t num)
 		vq_ring_free_chain(vq, desc_idx);
 
 		if (dxp->cookie != NULL) {
-			rte_pktmbuf_free(dxp->cookie);
+			dbg_pktmbuf_free(dxp->cookie);
 			dxp->cookie = NULL;
 		}
 	}
@@ -475,7 +476,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 	}
 
 	while (!virtqueue_full(vq)) {
-		m = rte_mbuf_raw_alloc(rxvq->mpool);
+		m = dbg_mbuf_raw_alloc(rxvq->mpool);
 		if (m == NULL)
 			break;
 
@@ -486,7 +487,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 			error = virtqueue_enqueue_recv_refill(vq, m);
 
 		if (error) {
-			rte_pktmbuf_free(m);
+			dbg_pktmbuf_free(m);
 			break;
 		}
 		nbufs++;
@@ -605,7 +606,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
 	error = virtqueue_enqueue_recv_refill(vq, m);
 	if (unlikely(error)) {
 		RTE_LOG(ERR, PMD, "cannot requeue discarded mbuf");
-		rte_pktmbuf_free(m);
+		dbg_pktmbuf_free(m);
 	}
 }
 
@@ -823,7 +824,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		}
 		error = virtqueue_enqueue_recv_refill(vq, new_mbuf);
 		if (unlikely(error)) {
-			rte_pktmbuf_free(new_mbuf);
+			dbg_pktmbuf_free(new_mbuf);
 			break;
 		}
 		nb_enqueued++;
@@ -996,7 +997,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
 		}
 		error = virtqueue_enqueue_recv_refill(vq, new_mbuf);
 		if (unlikely(error)) {
-			rte_pktmbuf_free(new_mbuf);
+			dbg_pktmbuf_free(new_mbuf);
 			break;
 		}
 		nb_enqueued++;
@@ -1045,7 +1046,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		if (unlikely(txm->ol_flags & PKT_TX_VLAN_PKT)) {
 			error = rte_vlan_insert(&txm);
 			if (unlikely(error)) {
-				rte_pktmbuf_free(txm);
+				dbg_pktmbuf_free(txm);
 				continue;
 			}
 		}
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 7be57ce66..2a21ddb03 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -49,6 +49,7 @@
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
 #include "virtio_user/virtio_user_dev.h"
+#include "virtio_alloc.h"
 
 #define virtio_user_get_dev(hw) \
 	((struct virtio_user_dev *)(hw)->virtio_user_dev)
@@ -356,11 +357,11 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	data = eth_dev->data;
 	hw = eth_dev->data->dev_private;
 
-	dev = rte_zmalloc(NULL, sizeof(*dev), 0);
+	dev = dbg_zmalloc(NULL, sizeof(*dev), 0);
 	if (!dev) {
 		PMD_INIT_LOG(ERR, "malloc virtio_user_dev failed");
 		rte_eth_dev_release_port(eth_dev);
-		rte_free(hw);
+		dbg_free(hw);
 		return NULL;
 	}
 
@@ -385,8 +386,8 @@ virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev)
 	struct rte_eth_dev_data *data = eth_dev->data;
 	struct virtio_hw *hw = data->dev_private;
 
-	rte_free(hw->virtio_user_dev);
-	rte_free(hw);
+	dbg_free(hw->virtio_user_dev);
+	dbg_free(hw);
 	rte_eth_dev_release_port(eth_dev);
 }
 
@@ -558,7 +559,7 @@ virtio_user_pmd_remove(struct rte_vdev_device *vdev)
 	dev = hw->virtio_user_dev;
 	virtio_user_dev_uninit(dev);
 
-	rte_free(eth_dev->data->dev_private);
+	dbg_free(eth_dev->data->dev_private);
 	rte_eth_dev_release_port(eth_dev);
 
 	return 0;
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index c3a536f8a..56efc94c8 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -37,6 +37,7 @@
 #include "virtqueue.h"
 #include "virtio_logs.h"
 #include "virtio_pci.h"
+#include "virtio_alloc.h"
 
 /*
  * Two types of mbuf to be cleaned:
@@ -77,7 +78,7 @@ virtqueue_flush(struct virtqueue *vq)
 		desc_idx = (uint16_t)uep->id;
 		dxp = &vq->vq_descx[desc_idx];
 		if (dxp->cookie != NULL) {
-			rte_pktmbuf_free(dxp->cookie);
+			dbg_pktmbuf_free(dxp->cookie);
 			dxp->cookie = NULL;
 		}
 		vq->vq_used_cons_idx++;
-- 
2.11.0

