From 1a7fa562fb5216386616b18b626fb9f21593bc05 Mon Sep 17 00:00:00 2001 From: Thomas Monjalon Date: Tue, 29 Sep 2020 01:14:19 +0200 Subject: [PATCH 1/1] net/failsafe: release port upon close The flag RTE_ETH_DEV_CLOSE_REMOVE is set so all port resources can be freed by rte_eth_dev_close(). Freeing of private port resources is moved from the ".remove(device)" to the ".dev_close(port)" operation. Signed-off-by: Thomas Monjalon Acked-by: Stephen Hemminger --- drivers/net/failsafe/failsafe.c | 25 ++-------- drivers/net/failsafe/failsafe_ops.c | 65 ++++++++++++++++--------- drivers/net/failsafe/failsafe_private.h | 1 + 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c index 4a4b7ceab6..44d47e8f72 100644 --- a/drivers/net/failsafe/failsafe.c +++ b/drivers/net/failsafe/failsafe.c @@ -60,12 +60,6 @@ fs_sub_device_alloc(struct rte_eth_dev *dev, return 0; } -static void -fs_sub_device_free(struct rte_eth_dev *dev) -{ - rte_free(PRIV(dev)->subs); -} - static void fs_hotplug_alarm(void *arg); int @@ -186,6 +180,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) ERROR("Unable to allocate rte_eth_dev"); return -1; } + dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; priv = PRIV(dev); priv->data = dev->data; priv->rxp = FS_RX_PROXY_INIT; @@ -285,7 +280,7 @@ unregister_new_callback: free_args: failsafe_args_free(dev); free_subs: - fs_sub_device_free(dev); + rte_free(PRIV(dev)->subs); free_dev: /* mac_addrs must not be freed alone because part of dev_private */ dev->data->mac_addrs = NULL; @@ -301,20 +296,8 @@ fs_rte_eth_free(const char *name) dev = rte_eth_dev_allocated(name); if (dev == NULL) - return -ENODEV; - rte_eth_dev_callback_unregister(RTE_ETH_ALL, RTE_ETH_EVENT_NEW, - failsafe_eth_new_event_callback, dev); - ret = failsafe_eal_uninit(dev); - if (ret) - ERROR("Error while uninitializing sub-EAL"); - failsafe_args_free(dev); - fs_sub_device_free(dev); - ret = pthread_mutex_destroy(&PRIV(dev)->hotplug_mutex); - if (ret) - ERROR("Error while destroying hotplug mutex"); - rte_free(PRIV(dev)->mcast_addrs); - /* mac_addrs must not be freed alone because part of dev_private */ - dev->data->mac_addrs = NULL; + return 0; /* port already released */ + ret = failsafe_eth_dev_close(dev); rte_eth_dev_release_port(dev); return ret; } diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c index 93ebd09114..0ce7dfc8a6 100644 --- a/drivers/net/failsafe/failsafe_ops.c +++ b/drivers/net/failsafe/failsafe_ops.c @@ -239,29 +239,6 @@ fs_dev_set_link_down(struct rte_eth_dev *dev) return 0; } -static void fs_dev_free_queues(struct rte_eth_dev *dev); -static int -fs_dev_close(struct rte_eth_dev *dev) -{ - struct sub_device *sdev; - uint8_t i; - - fs_lock(dev, 0); - failsafe_hotplug_alarm_cancel(dev); - if (PRIV(dev)->state == DEV_STARTED) - dev->dev_ops->dev_stop(dev); - PRIV(dev)->state = DEV_ACTIVE - 1; - FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { - DEBUG("Closing sub_device %d", i); - failsafe_eth_dev_unregister_callbacks(sdev); - rte_eth_dev_close(PORT_ID(sdev)); - sdev->state = DEV_ACTIVE - 1; - } - fs_dev_free_queues(dev); - fs_unlock(dev, 0); - return 0; -} - static int fs_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) { @@ -656,6 +633,46 @@ fs_dev_free_queues(struct rte_eth_dev *dev) dev->data->nb_tx_queues = 0; } +int +failsafe_eth_dev_close(struct rte_eth_dev *dev) +{ + struct sub_device *sdev; + uint8_t i; + int ret; + + fs_lock(dev, 0); + failsafe_hotplug_alarm_cancel(dev); + if (PRIV(dev)->state == DEV_STARTED) + dev->dev_ops->dev_stop(dev); + PRIV(dev)->state = DEV_ACTIVE - 1; + FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { + DEBUG("Closing sub_device %d", i); + failsafe_eth_dev_unregister_callbacks(sdev); + rte_eth_dev_close(PORT_ID(sdev)); + sdev->state = DEV_ACTIVE - 1; + } + rte_eth_dev_callback_unregister(RTE_ETH_ALL, RTE_ETH_EVENT_NEW, + failsafe_eth_new_event_callback, dev); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + fs_unlock(dev, 0); + return 0; + } + fs_dev_free_queues(dev); + ret = failsafe_eal_uninit(dev); + if (ret) + ERROR("Error while uninitializing sub-EAL"); + failsafe_args_free(dev); + rte_free(PRIV(dev)->subs); + rte_free(PRIV(dev)->mcast_addrs); + /* mac_addrs must not be freed alone because part of dev_private */ + dev->data->mac_addrs = NULL; + fs_unlock(dev, 0); + ret = pthread_mutex_destroy(&PRIV(dev)->hotplug_mutex); + if (ret) + ERROR("Error while destroying hotplug mutex"); + return 0; +} + static int fs_promiscuous_enable(struct rte_eth_dev *dev) { @@ -1484,7 +1501,7 @@ const struct eth_dev_ops failsafe_ops = { .dev_stop = fs_dev_stop, .dev_set_link_down = fs_dev_set_link_down, .dev_set_link_up = fs_dev_set_link_up, - .dev_close = fs_dev_close, + .dev_close = failsafe_eth_dev_close, .promiscuous_enable = fs_promiscuous_enable, .promiscuous_disable = fs_promiscuous_disable, .allmulticast_enable = fs_allmulticast_enable, diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h index 651578a128..6af0ef8471 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -236,6 +236,7 @@ int failsafe_eal_uninit(struct rte_eth_dev *dev); int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev); void failsafe_eth_dev_unregister_callbacks(struct sub_device *sdev); +int failsafe_eth_dev_close(struct rte_eth_dev *dev); void failsafe_dev_remove(struct rte_eth_dev *dev); void failsafe_stats_increment(struct rte_eth_stats *to, struct rte_eth_stats *from); -- 2.20.1