From patchwork Fri Oct 16 13:32:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 81114 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 73E3AA04DB; Fri, 16 Oct 2020 15:34:26 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3B2691EE3D; Fri, 16 Oct 2020 15:33:30 +0200 (CEST) Received: from new3-smtp.messagingengine.com (new3-smtp.messagingengine.com [66.111.4.229]) by dpdk.org (Postfix) with ESMTP id 60EDD1EE3C for ; Fri, 16 Oct 2020 15:33:28 +0200 (CEST) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailnew.nyi.internal (Postfix) with ESMTP id D022F580324; Fri, 16 Oct 2020 09:33:27 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Fri, 16 Oct 2020 09:33:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monjalon.net; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=TgBu2Au2NXwiF jM5ajywX4pW+/g3bp//g9KPsoDQrOI=; b=OYkcbTUaMfAeAm6PtF3ScoXjM5KgT P8oJ9No0q5DW5A0E7UWamoHZrCEW+ayP8kFLqd7rL32o3QYIGClQIfeo0HOXA0tG kA9+3tF+33wo6YLOaSsVdLxZ8aU+LEnomwKEcEDXLz4Nmz6IcAwR+zLWt5OnCyCE xDffXPA0UW3Bogms0arG4/af7H/iOYfVn2KMYsrci4fDsJtB/Z6LlHFyBtHr9gm0 XVqKkt/zJ/yukm5WJywkJP6X/7uQEXSMs0BYYkiuz17e26GIH8PFNyMraY1nXWAD aqd57WR2Y2oDb/q3Rx407OHyJ5cGU9nsYrrqXwpsgFD39KKDDDg3Uoi4g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=TgBu2Au2NXwiFjM5ajywX4pW+/g3bp//g9KPsoDQrOI=; b=nTYrtO8g zRcr0e0iaqNgOb0OxErGzR39V8oVVi6gXbgxBVojnmBHBSuU4YbhYsB0uuGRIZrI 8LqSPj3UjibNJRlKZiRUWmCn/maSRqt068Efp9BvXmAttvsQFFTz9j7Y54BO1UyP mrU3LoBKv3fmj2pjGIhQ4jn2wn8+qIOFg35p5m1umUrvoBwXSdSwRU0kMIETDU1v 5ifo9FCBGQQDMMDf4oWQJwGcQdg4UrTkt7A33AIpvZPrV8385PzMF+t+2QDfx4k9 iqjtdIghlkoTDoGXCXqXx4sD01hOQlyBTgTXmSCph9bUGkC+sNx1RCbd7XVR6pS6 IifsqfaTBAfLtA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrieehgdeiiecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfhhohhmrghs ucfoohhnjhgrlhhonhcuoehthhhomhgrshesmhhonhhjrghlohhnrdhnvghtqeenucggtf frrghtthgvrhhnpedvhefgiedvjeegtdevheefhfetleefgfeivefgffevfeejgedtgfeu tdehtdegveenucfkphepjeejrddufeegrddvtdefrddukeegnecuvehluhhsthgvrhfuih iivgepfeenucfrrghrrghmpehmrghilhhfrhhomhepthhhohhmrghssehmohhnjhgrlhho nhdrnhgvth X-ME-Proxy: Received: from xps.monjalon.net (184.203.134.77.rev.sfr.net [77.134.203.184]) by mail.messagingengine.com (Postfix) with ESMTPA id 1037C3064683; Fri, 16 Oct 2020 09:33:24 -0400 (EDT) From: Thomas Monjalon To: dev@dpdk.org Cc: ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru, Liron Himi , Stephen Hemminger , Ray Kinsella , Neil Horman , Rahul Lakkireddy , Gaetan Rivet , Jakub Grajciar , Matan Azrad , Shahaf Shuler , Viacheslav Ovsiienko , Zyta Szpak , Stephen Hemminger , "K. Y. Srinivasan" , Haiyang Zhang , Long Li , Maxime Coquelin , Chenbo Xia , Zhihong Wang Date: Fri, 16 Oct 2020 15:32:59 +0200 Message-Id: <20201016133259.3061153-4-thomas@monjalon.net> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201016133259.3061153-1-thomas@monjalon.net> References: <20200913220711.3768597-1-thomas@monjalon.net> <20201016133259.3061153-1-thomas@monjalon.net> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v6 3/3] ethdev: allow close function to return an error X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The API function rte_eth_dev_close() was returning void. The return type is changed to int for notifying of errors. If an error happens during a close operation, the status of the port is undefined, a maximum of resources having been freed. Signed-off-by: Thomas Monjalon Reviewed-by: Liron Himi Acked-by: Stephen Hemminger Acked-by: Andrew Rybchenko Reviewed-by: Ferruh Yigit --- doc/guides/rel_notes/deprecation.rst | 1 - doc/guides/rel_notes/release_20_11.rst | 4 +++- drivers/net/cxgbe/cxgbe_ethdev.c | 5 +++-- drivers/net/cxgbe/cxgbevf_ethdev.c | 5 +++-- drivers/net/failsafe/failsafe_ether.c | 6 +++++- drivers/net/failsafe/failsafe_ops.c | 25 +++++++++++++++++-------- drivers/net/memif/rte_eth_memif.c | 4 +--- drivers/net/mlx5/mlx5.c | 7 ++++--- drivers/net/mvneta/mvneta_ethdev.c | 5 +++-- drivers/net/mvpp2/mrvl_ethdev.c | 5 +++-- drivers/net/netvsc/hn_ethdev.c | 6 ++++-- drivers/net/netvsc/hn_var.h | 2 +- drivers/net/netvsc/hn_vf.c | 7 +++++-- drivers/net/virtio/virtio_user_ethdev.c | 4 +--- lib/librte_ethdev/rte_ethdev.c | 16 +++++++++++----- lib/librte_ethdev/rte_ethdev.h | 5 ++++- 16 files changed, 68 insertions(+), 39 deletions(-) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 6cbfd11847..6e7bd14a46 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -128,7 +128,6 @@ Deprecation Notices invalid port ID, unsupported operation, failed operation): - ``rte_eth_dev_stop`` - - ``rte_eth_dev_close`` * ethdev: New offload flags ``DEV_RX_OFFLOAD_FLOW_MARK`` will be added in 19.11. This will allow application to enable or disable PMDs from updating diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst index 48717ee536..b53cff2adc 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -369,7 +369,9 @@ API Changes * ethdev: ``rte_eth_rx_descriptor_done()`` API has been deprecated. -* Renamed internal ethdev APIs: +* ethdev: Added ``int`` return type to ``rte_eth_dev_close()``. + +* ethdev: Renamed internal functions: * ``_rte_eth_dev_callback_process()`` -> ``rte_eth_dev_callback_process()`` * ``_rte_eth_dev_reset`` -> ``rte_eth_dev_internal_reset()`` diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c index 16beb2d435..fe488231a7 100644 --- a/drivers/net/cxgbe/cxgbe_ethdev.c +++ b/drivers/net/cxgbe/cxgbe_ethdev.c @@ -1296,12 +1296,13 @@ static int eth_cxgbe_dev_uninit(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); uint16_t port_id; + int err = 0; /* Free up other ports and all resources */ RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) - rte_eth_dev_close(port_id); + err |= rte_eth_dev_close(port_id); - return 0; + return err == 0 ? 0 : -EIO; } static int eth_cxgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, diff --git a/drivers/net/cxgbe/cxgbevf_ethdev.c b/drivers/net/cxgbe/cxgbevf_ethdev.c index 947fcdd406..c2918f5356 100644 --- a/drivers/net/cxgbe/cxgbevf_ethdev.c +++ b/drivers/net/cxgbe/cxgbevf_ethdev.c @@ -183,12 +183,13 @@ static int eth_cxgbevf_dev_uninit(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); uint16_t port_id; + int err = 0; /* Free up other ports and all resources */ RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) - rte_eth_dev_close(port_id); + err |= rte_eth_dev_close(port_id); - return 0; + return err == 0 ? 0 : -EIO; } static int eth_cxgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, diff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c index 7c68bbdec0..950d35dac4 100644 --- a/drivers/net/failsafe/failsafe_ether.c +++ b/drivers/net/failsafe/failsafe_ether.c @@ -287,7 +287,11 @@ fs_dev_remove(struct sub_device *sdev) /* fallthrough */ case DEV_ACTIVE: failsafe_eth_dev_unregister_callbacks(sdev); - rte_eth_dev_close(PORT_ID(sdev)); + ret = rte_eth_dev_close(PORT_ID(sdev)); + if (ret < 0) { + ERROR("Port close failed for sub-device %u", + PORT_ID(sdev)); + } sdev->state = DEV_PROBED; /* fallthrough */ case DEV_PROBED: diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c index 0ce7dfc8a6..5c606ff077 100644 --- a/drivers/net/failsafe/failsafe_ops.c +++ b/drivers/net/failsafe/failsafe_ops.c @@ -638,7 +638,7 @@ failsafe_eth_dev_close(struct rte_eth_dev *dev) { struct sub_device *sdev; uint8_t i; - int ret; + int err, ret = 0; fs_lock(dev, 0); failsafe_hotplug_alarm_cancel(dev); @@ -648,29 +648,38 @@ failsafe_eth_dev_close(struct rte_eth_dev *dev) 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)); + err = rte_eth_dev_close(PORT_ID(sdev)); + if (err) { + ret = ret ? ret : err; + ERROR("Error while closing sub-device %u", + 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; + return ret; } fs_dev_free_queues(dev); - ret = failsafe_eal_uninit(dev); - if (ret) + err = failsafe_eal_uninit(dev); + if (err) { + ret = ret ? ret : err; 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) + err = pthread_mutex_destroy(&PRIV(dev)->hotplug_mutex); + if (err) { + ret = ret ? ret : err; ERROR("Error while destroying hotplug mutex"); - return 0; + } + return ret; } static int diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c index ff8a58081f..33bf5c68a3 100644 --- a/drivers/net/memif/rte_eth_memif.c +++ b/drivers/net/memif/rte_eth_memif.c @@ -1798,9 +1798,7 @@ rte_pmd_memif_remove(struct rte_vdev_device *vdev) if (eth_dev == NULL) return 0; - rte_eth_dev_close(eth_dev->data->port_id); - - return 0; + return rte_eth_dev_close(eth_dev->data->port_id); } static struct rte_vdev_driver pmd_memif_drv = { diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index e5ca392fed..dc55988b10 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -2020,6 +2020,7 @@ static int mlx5_pci_remove(struct rte_pci_device *pci_dev) { uint16_t port_id; + int ret = 0; RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) { /* @@ -2027,11 +2028,11 @@ mlx5_pci_remove(struct rte_pci_device *pci_dev) * call the close function explicitly for secondary process. */ if (rte_eal_process_type() == RTE_PROC_SECONDARY) - mlx5_dev_close(&rte_eth_devices[port_id]); + ret |= mlx5_dev_close(&rte_eth_devices[port_id]); else - rte_eth_dev_close(port_id); + ret |= rte_eth_dev_close(port_id); } - return 0; + return ret == 0 ? 0 : -EIO; } static const struct rte_pci_id mlx5_pci_id_map[] = { diff --git a/drivers/net/mvneta/mvneta_ethdev.c b/drivers/net/mvneta/mvneta_ethdev.c index 3c0332ab4d..1574bf35a8 100644 --- a/drivers/net/mvneta/mvneta_ethdev.c +++ b/drivers/net/mvneta/mvneta_ethdev.c @@ -966,14 +966,15 @@ static int rte_pmd_mvneta_remove(struct rte_vdev_device *vdev) { uint16_t port_id; + int ret = 0; RTE_ETH_FOREACH_DEV(port_id) { if (rte_eth_devices[port_id].device != &vdev->device) continue; - rte_eth_dev_close(port_id); + ret |= rte_eth_dev_close(port_id); } - return 0; + return ret == 0 ? 0 : -EIO; } static struct rte_vdev_driver pmd_mvneta_drv = { diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c index a230a96840..df9f336fab 100644 --- a/drivers/net/mvpp2/mrvl_ethdev.c +++ b/drivers/net/mvpp2/mrvl_ethdev.c @@ -3022,14 +3022,15 @@ static int rte_pmd_mrvl_remove(struct rte_vdev_device *vdev) { uint16_t port_id; + int ret = 0; RTE_ETH_FOREACH_DEV(port_id) { if (rte_eth_devices[port_id].device != &vdev->device) continue; - rte_eth_dev_close(port_id); + ret |= rte_eth_dev_close(port_id); } - return 0; + return ret == 0 ? 0 : -EIO; } static struct rte_vdev_driver pmd_mrvl_drv = { diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c index 8743e6e69a..40e6d25f34 100644 --- a/drivers/net/netvsc/hn_ethdev.c +++ b/drivers/net/netvsc/hn_ethdev.c @@ -842,14 +842,16 @@ hn_dev_stop(struct rte_eth_dev *dev) static int hn_dev_close(struct rte_eth_dev *dev) { + int ret; + PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - hn_vf_close(dev); + ret = hn_vf_close(dev); hn_dev_free_queues(dev); - return 0; + return ret; } static const struct eth_dev_ops hn_eth_dev_ops = { diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index 4b63f87607..74f30669ac 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -217,7 +217,7 @@ const uint32_t *hn_vf_supported_ptypes(struct rte_eth_dev *dev); int hn_vf_start(struct rte_eth_dev *dev); void hn_vf_reset(struct rte_eth_dev *dev); void hn_vf_stop(struct rte_eth_dev *dev); -void hn_vf_close(struct rte_eth_dev *dev); +int hn_vf_close(struct rte_eth_dev *dev); int hn_vf_allmulticast_enable(struct rte_eth_dev *dev); int hn_vf_allmulticast_disable(struct rte_eth_dev *dev); diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c index f5f15c0462..d29eee7627 100644 --- a/drivers/net/netvsc/hn_vf.c +++ b/drivers/net/netvsc/hn_vf.c @@ -316,18 +316,21 @@ void hn_vf_reset(struct rte_eth_dev *dev) VF_ETHDEV_FUNC(dev, rte_eth_dev_reset); } -void hn_vf_close(struct rte_eth_dev *dev) +int hn_vf_close(struct rte_eth_dev *dev) { struct hn_data *hv = dev->data->dev_private; uint16_t vf_port; + int ret = 0; rte_rwlock_read_lock(&hv->vf_lock); vf_port = hv->vf_port; if (vf_port != HN_INVALID_PORT) - rte_eth_dev_close(vf_port); + ret = rte_eth_dev_close(vf_port); hv->vf_port = HN_INVALID_PORT; rte_rwlock_read_unlock(&hv->vf_lock); + + return ret; } int hn_vf_stats_reset(struct rte_eth_dev *dev) diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index f56fc238c4..042665bc09 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -881,9 +881,7 @@ virtio_user_pmd_remove(struct rte_vdev_device *vdev) return rte_eth_dev_release_port(eth_dev); /* make sure the device is stopped, queues freed */ - rte_eth_dev_close(eth_dev->data->port_id); - - return 0; + return rte_eth_dev_close(eth_dev->data->port_id); } static int virtio_user_pmd_dma_map(struct rte_vdev_device *vdev, void *addr, diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 3ae2253b9d..11ad32ca61 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -1718,19 +1718,25 @@ rte_eth_dev_set_link_down(uint16_t port_id) return eth_err(port_id, (*dev->dev_ops->dev_set_link_down)(dev)); } -void +int rte_eth_dev_close(uint16_t port_id) { struct rte_eth_dev *dev; + int firsterr, binerr; + int *lasterr = &firsterr; - RTE_ETH_VALID_PORTID_OR_RET(port_id); + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); dev = &rte_eth_devices[port_id]; - RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_close); - (*dev->dev_ops->dev_close)(dev); + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); + *lasterr = (*dev->dev_ops->dev_close)(dev); + if (*lasterr != 0) + lasterr = &binerr; rte_ethdev_trace_close(port_id); - rte_eth_dev_release_port(dev); + *lasterr = rte_eth_dev_release_port(dev); + + return eth_err(port_id, firsterr); } int diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 500b2ff766..849bcaf85e 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -2306,8 +2306,11 @@ int rte_eth_dev_set_link_down(uint16_t port_id); * * @param port_id * The port identifier of the Ethernet device. + * @return + * - Zero if the port is closed successfully. + * - Negative if something went wrong. */ -void rte_eth_dev_close(uint16_t port_id); +int rte_eth_dev_close(uint16_t port_id); /** * Reset a Ethernet device and keep its port id.