Skip to content

Commit

Permalink
netdev-dpdk: fix memory leak
Browse files Browse the repository at this point in the history
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).

Signed-off-by: Mark Kavanagh <[email protected]>
Signed-off-by: Daniele Di Proietto <[email protected]>
  • Loading branch information
mark-kavanagh authored and ddiproietto committed Aug 4, 2016
1 parent 94cf215 commit 8d38823
Showing 1 changed file with 14 additions and 15 deletions.
29 changes: 14 additions & 15 deletions lib/netdev-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,23 +506,18 @@ 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) {
return;
}

dmp->refcount--;
ovs_assert(dmp->refcount >= 0);
ovs_assert(dmp->refcount);

#if 0
/* I could not find any API to destroy mp. */
if (dmp->refcount == 0) {
list_delete(dmp->list_node);
/* destroy mp-pool. */
if (!--dmp->refcount) {
ovs_list_remove(&dmp->list_node);
rte_mempool_free(dmp->mp);
}
#endif
}

static void
Expand Down Expand Up @@ -928,16 +923,18 @@ 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);
}

Expand All @@ -946,6 +943,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 (netdev_dpdk_get_vid(dev) >= 0) {
VLOG_ERR("Removing port '%s' while vhost device still attached.",
Expand All @@ -961,15 +961,14 @@ 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);
}

Expand Down

0 comments on commit 8d38823

Please sign in to comment.