mirror of
https://github.com/openvswitch/ovs
synced 2025-09-02 07:15:17 +00:00
netdev-dpdk: fix memory leak
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 <mark.b.kavanagh@intel.com> Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com>
This commit is contained in:
committed by
Daniele Di Proietto
parent
94cf215ed4
commit
8d38823bdf
@@ -506,23 +506,18 @@ dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dpdk_mp_put(struct dpdk_mp *dmp)
|
dpdk_mp_put(struct dpdk_mp *dmp) OVS_REQUIRES(dpdk_mutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!dmp) {
|
if (!dmp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmp->refcount--;
|
ovs_assert(dmp->refcount);
|
||||||
ovs_assert(dmp->refcount >= 0);
|
|
||||||
|
|
||||||
#if 0
|
if (!--dmp->refcount) {
|
||||||
/* I could not find any API to destroy mp. */
|
ovs_list_remove(&dmp->list_node);
|
||||||
if (dmp->refcount == 0) {
|
rte_mempool_free(dmp->mp);
|
||||||
list_delete(dmp->list_node);
|
|
||||||
/* destroy mp-pool. */
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -928,16 +923,18 @@ netdev_dpdk_destruct(struct netdev *netdev)
|
|||||||
{
|
{
|
||||||
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
|
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
|
||||||
|
|
||||||
|
ovs_mutex_lock(&dpdk_mutex);
|
||||||
ovs_mutex_lock(&dev->mutex);
|
ovs_mutex_lock(&dev->mutex);
|
||||||
|
|
||||||
rte_eth_dev_stop(dev->port_id);
|
rte_eth_dev_stop(dev->port_id);
|
||||||
free(ovsrcu_get_protected(struct ingress_policer *,
|
free(ovsrcu_get_protected(struct ingress_policer *,
|
||||||
&dev->ingress_policer));
|
&dev->ingress_policer));
|
||||||
ovs_mutex_unlock(&dev->mutex);
|
|
||||||
|
|
||||||
ovs_mutex_lock(&dpdk_mutex);
|
|
||||||
rte_free(dev->tx_q);
|
rte_free(dev->tx_q);
|
||||||
ovs_list_remove(&dev->list_node);
|
ovs_list_remove(&dev->list_node);
|
||||||
dpdk_mp_put(dev->dpdk_mp);
|
dpdk_mp_put(dev->dpdk_mp);
|
||||||
|
|
||||||
|
ovs_mutex_unlock(&dev->mutex);
|
||||||
ovs_mutex_unlock(&dpdk_mutex);
|
ovs_mutex_unlock(&dpdk_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -946,6 +943,9 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev)
|
|||||||
{
|
{
|
||||||
struct netdev_dpdk *dev = netdev_dpdk_cast(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. */
|
/* Guest becomes an orphan if still attached. */
|
||||||
if (netdev_dpdk_get_vid(dev) >= 0) {
|
if (netdev_dpdk_get_vid(dev) >= 0) {
|
||||||
VLOG_ERR("Removing port '%s' while vhost device still attached.",
|
VLOG_ERR("Removing port '%s' while vhost device still attached.",
|
||||||
@@ -961,15 +961,14 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev)
|
|||||||
fatal_signal_remove_file_to_unlink(dev->vhost_id);
|
fatal_signal_remove_file_to_unlink(dev->vhost_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ovs_mutex_lock(&dev->mutex);
|
|
||||||
free(ovsrcu_get_protected(struct ingress_policer *,
|
free(ovsrcu_get_protected(struct ingress_policer *,
|
||||||
&dev->ingress_policer));
|
&dev->ingress_policer));
|
||||||
ovs_mutex_unlock(&dev->mutex);
|
|
||||||
|
|
||||||
ovs_mutex_lock(&dpdk_mutex);
|
|
||||||
rte_free(dev->tx_q);
|
rte_free(dev->tx_q);
|
||||||
ovs_list_remove(&dev->list_node);
|
ovs_list_remove(&dev->list_node);
|
||||||
dpdk_mp_put(dev->dpdk_mp);
|
dpdk_mp_put(dev->dpdk_mp);
|
||||||
|
|
||||||
|
ovs_mutex_unlock(&dev->mutex);
|
||||||
ovs_mutex_unlock(&dpdk_mutex);
|
ovs_mutex_unlock(&dpdk_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user