diff mbox

[ovs-dev,RFC] netdev-dpdk: fix memory leak

Message ID 1469720481-158410-1-git-send-email-mark.b.kavanagh@intel.com
State Superseded
Delegated to: Daniele Di Proietto
Headers show

Commit Message

Mark Kavanagh July 28, 2016, 3:41 p.m. UTC
DPDK v16.07 introduces the ability to free memzones.
Up until this point, DPDK memory pools created in OVS could
not be destroyed, thus incurring a memory leak.

Leverage the DPDK v16.07 rte_mempool API to free DPDK
mempools when their associated reference count reaches 0 (this
indicates that the memory pool is no longer in use).

Until DPDK v16.07 is supported, this patch may be considered RFC.

Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
---
 lib/netdev-dpdk.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)
diff mbox

Patch

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index dfb26d4..b9027a7 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -505,7 +505,7 @@  dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
 }
 
 static void
-dpdk_mp_put(struct dpdk_mp *dmp)
+dpdk_mp_put(struct dpdk_mp *dmp) OVS_REQUIRES(dpdk_mutex)
 {
 
     if (!dmp) {
@@ -513,15 +513,11 @@  dpdk_mp_put(struct dpdk_mp *dmp)
     }
 
     dmp->refcount--;
-    ovs_assert(dmp->refcount >= 0);
 
-#if 0
-    /* I could not find any API to destroy mp. */
-    if (dmp->refcount == 0) {
-        list_delete(dmp->list_node);
-        /* destroy mp-pool. */
+    if (OVS_UNLIKELY(!dmp->refcount)) {
+        ovs_list_remove(&dmp->list_node);
+        rte_mempool_free(dmp->mp);
     }
-#endif
 }
 
 static void
@@ -909,16 +905,17 @@  netdev_dpdk_destruct(struct netdev *netdev)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
 
+    ovs_mutex_lock(&dpdk_mutex);
     ovs_mutex_lock(&dev->mutex);
+
     rte_eth_dev_stop(dev->port_id);
     free(ovsrcu_get_protected(struct ingress_policer *,
                               &dev->ingress_policer));
-    ovs_mutex_unlock(&dev->mutex);
-
-    ovs_mutex_lock(&dpdk_mutex);
     rte_free(dev->tx_q);
     ovs_list_remove(&dev->list_node);
     dpdk_mp_put(dev->dpdk_mp);
+
+    ovs_mutex_unlock(&dev->mutex);
     ovs_mutex_unlock(&dpdk_mutex);
 }
 
@@ -933,6 +930,9 @@  netdev_dpdk_vhost_destruct(struct netdev *netdev)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
 
+    ovs_mutex_lock(&dpdk_mutex);
+    ovs_mutex_lock(&dev->mutex);
+
     /* Guest becomes an orphan if still attached. */
     if (is_vhost_running(dev->vid)) {
         VLOG_ERR("Removing port '%s' while vhost device still attached.",
@@ -948,15 +948,13 @@  netdev_dpdk_vhost_destruct(struct netdev *netdev)
         fatal_signal_remove_file_to_unlink(dev->vhost_id);
     }
 
-    ovs_mutex_lock(&dev->mutex);
     free(ovsrcu_get_protected(struct ingress_policer *,
                               &dev->ingress_policer));
-    ovs_mutex_unlock(&dev->mutex);
-
-    ovs_mutex_lock(&dpdk_mutex);
     rte_free(dev->tx_q);
     ovs_list_remove(&dev->list_node);
     dpdk_mp_put(dev->dpdk_mp);
+
+    ovs_mutex_unlock(&dev->mutex);
     ovs_mutex_unlock(&dpdk_mutex);
 }
 
@@ -1614,6 +1612,7 @@  netdev_dpdk_set_mtu(const struct netdev *netdev, int mtu)
 
     ovs_mutex_lock(&dpdk_mutex);
     ovs_mutex_lock(&dev->mutex);
+
     if (dev->mtu == mtu) {
         err = 0;
         goto out;