diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 21f1dfbe4f..741a864f7b 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -362,6 +362,18 @@ rte_eth_dev_attach_secondary(const char *name) return eth_dev; } +int +rte_eth_dev_release_port_secondary(struct rte_eth_dev *eth_dev) +{ + if (eth_dev == NULL) + return -EINVAL; + + _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_DESTROY, NULL); + eth_dev->state = RTE_ETH_DEV_UNUSED; + + return 0; +} + int rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) { @@ -3578,9 +3590,10 @@ rte_eth_dev_destroy(struct rte_eth_dev *ethdev, return ret; } - if (rte_eal_process_type() == RTE_PROC_PRIMARY) - rte_free(ethdev->data->dev_private); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return rte_eth_dev_release_port_secondary(ethdev); + rte_free(ethdev->data->dev_private); ethdev->data->dev_private = NULL; return rte_eth_dev_release_port(ethdev); diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h index f158462a01..ca31b57776 100644 --- a/lib/librte_ethdev/rte_ethdev_driver.h +++ b/lib/librte_ethdev/rte_ethdev_driver.h @@ -61,12 +61,26 @@ struct rte_eth_dev *rte_eth_dev_attach_secondary(const char *name); * Release the specified ethdev port. * * @param eth_dev - * The *eth_dev* pointer is the address of the *rte_eth_dev* structure. + * Device to be detached. * @return * - 0 on success, negative on error */ int rte_eth_dev_release_port(struct rte_eth_dev *eth_dev); +/** + * @internal + * Release the specified ethdev port in the local process. + * Only set ethdev state to unused, but not reset shared data since + * it assume other processes is still using it. typically it is + * called by a secondary process. + * + * @param eth_dev + * Device to be detached. + * @return + * - 0 on success, negative on error + */ +int rte_eth_dev_release_port_secondary(struct rte_eth_dev *eth_dev); + /** * @internal * Release device queues and clear its configuration to force the user diff --git a/lib/librte_ethdev/rte_ethdev_pci.h b/lib/librte_ethdev/rte_ethdev_pci.h index f652596f4c..70d2d25036 100644 --- a/lib/librte_ethdev/rte_ethdev_pci.h +++ b/lib/librte_ethdev/rte_ethdev_pci.h @@ -135,9 +135,15 @@ rte_eth_dev_pci_allocate(struct rte_pci_device *dev, size_t private_data_size) static inline void rte_eth_dev_pci_release(struct rte_eth_dev *eth_dev) { - if (rte_eal_process_type() == RTE_PROC_PRIMARY) - rte_free(eth_dev->data->dev_private); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + eth_dev->device = NULL; + eth_dev->intr_handle = NULL; + rte_eth_dev_release_port_secondary(eth_dev); + return; + } + /* primary process */ + rte_free(eth_dev->data->dev_private); eth_dev->data->dev_private = NULL; /* diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index dfa122c1a0..3a4dd47901 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -220,6 +220,13 @@ DPDK_18.08 { } DPDK_18.05; +DPDK_18.11 { + global: + + rte_eth_dev_release_port_secondary; + +} DPDK_18.08; + EXPERIMENTAL { global: