The secondary processes are not allowed to release shared resources.
Only process-private resources should be freed in a secondary process.
Most of the time, there is no process-private resource,
so the close operation is just forbidden in a secondary process.
After adding proper check in the port close functions,
some redundant checks in the device remove functions are dropped.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Rosen Xu <rosen.xu@intel.com>
Reviewed-by: Sachin Saxena <sachin.saxena@oss.nxp.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Liron Himi <lironh@marvell.com>
Reviewed-by: Haiyue Wang <haiyue.wang@intel.com>
Acked-by: Jeff Guo <jia.guo@intel.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
        struct pkt_rx_queue *rxq;
        int i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        AF_XDP_LOG(INFO, "Closing AF_XDP ethdev on numa socket %u\n",
                rte_socket_id());
 
 
        struct ark_adapter *ark = dev->data->dev_private;
        uint16_t i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (ark->user_ext.dev_close)
                ark->user_ext.dev_close(dev,
                 ark->user_data[dev->data->port_id]);
 
        struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        int ret;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        rte_spinlock_lock(&avp->lock);
        if (avp->flags & AVP_F_DETACHED) {
                PMD_DRV_LOG(ERR, "Operation not supported during VM live migration\n");
 
 {
        struct bnxt *bp = eth_dev->data->dev_private;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        /* cancel the recovery handler before remove dev */
        rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp);
        rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
 
                (struct bnxt_representor *)eth_dev->data->dev_private;
        uint16_t vf_id;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR uninit\n", eth_dev->data->port_id);
        eth_dev->data->mac_addrs = NULL;
        eth_dev->dev_ops = NULL;
 
 
        CXGBE_FUNC_TRACE();
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (!(adapter->flags & FULL_INIT_DONE))
                return 0;
 
 
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        eth_em_stop(dev);
        adapter->stopped = 1;
        em_dev_free_queues(dev);
 
        struct e1000_filter_info *filter_info =
                E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        eth_igb_stop(dev);
 
        e1000_phy_hw_reset(hw);
 
        PMD_INIT_FUNC_TRACE();
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        e1000_reset_hw(hw);
 
        igbvf_dev_stop(dev);
 
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ena_adapter *adapter = dev->data->dev_private;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (adapter->state == ENA_ADAPTER_STATE_RUNNING)
                ena_stop(dev);
        adapter->state = ENA_ADAPTER_STATE_CLOSED;
 
        uint16_t i;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        enetc_dev_stop(dev);
 
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
 
        struct enic *enic = pmd_priv(eth_dev);
 
        ENICPMD_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        enic_remove(enic);
 
        return 0;
 
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        fm10k_mbx_lock(hw);
        hw->mac.ops.update_lport_state(hw, hw->mac.dglort_map,
 eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
 {
        PMD_INIT_FUNC_TRACE();
-
-       /* only uninitialize in the primary process */
-       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-               return 0;
-
-       /* safe to close dev here */
        fm10k_dev_close(dev);
-
        return 0;
 }
 
 
 {
        struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (rte_bit_relaxed_test_and_set32(HINIC_DEV_CLOSE,
                                           &nic_dev->dev_status)) {
                PMD_DRV_LOG(WARNING, "Device %s already closed",
 
        int retries = 0;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        ret = rte_eth_switch_domain_free(pf->switch_domain_id);
        if (ret)
 
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        i40evf_dev_stop(dev);
        i40e_dev_free_queues(dev);
        /*
 
                IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        iavf_dev_stop(dev);
        iavf_flow_flush(dev, NULL);
        iavf_flow_uninit(adapter);
 
        struct ice_adapter *ad =
                ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        /* Since stop will make link down, then the link event will be
         * triggered, disable the irq firstly to avoid the port_infoe etc
         * resources deallocation causing the interrupt service thread
 
        int retry = 0;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        if (!adapter->stopped)
                eth_igc_stop(dev);
 eth_igc_dev_uninit(__rte_unused struct rte_eth_dev *eth_dev)
 {
        PMD_INIT_FUNC_TRACE();
-
-       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-               return 0;
-
        eth_igc_close(eth_dev);
        return 0;
 }
 
        int err;
 
        IONIC_PRINT_CALL();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        err = ionic_lif_stop(lif);
        if (err) {
 
        struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
        struct ipn3ke_rpst *rpst = IPN3KE_DEV_PRIVATE_TO_RPST(dev);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
                /* Disable the TX path */
                ipn3ke_xmac_tx_disable(hw, rpst->port_id, 0);
 
        int ret;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        ixgbe_pf_reset_hw(hw);
 
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        ixgbe_reset_hw(hw);
 
 
        struct pmd_internals *internals;
        int ret;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        eth_kni_dev_stop(eth_dev);
 
        /* mac_addrs must not be freed alone because part of dev_private */
 
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        lio_dev_info(lio_dev, "closing port %d\n", eth_dev->data->port_id);
 
        if (lio_dev->intf_open)
 
        struct mlx4_priv *priv = dev->data->dev_private;
        unsigned int i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
        DEBUG("%p: closing device \"%s\"",
              (void *)dev,
              ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
 
        struct mvneta_priv *priv = dev->data->dev_private;
        int i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        if (priv->ppio)
                mvneta_dev_stop(dev);
 
 
        struct mrvl_priv *priv = dev->data->dev_private;
        size_t i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        mrvl_flush_rx_queues(dev);
        mrvl_flush_tx_shadow_queues(dev);
        mrvl_flow_deinit(dev);
 
 hn_dev_close(struct rte_eth_dev *dev)
 {
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        hn_vf_close(dev);
        hn_dev_free_queues(dev);
 
        uint16_t nb_rx = dev->data->nb_rx_queues;
        uint16_t nb_tx = dev->data->nb_tx_queues;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        nfb_eth_dev_stop(dev);
 
        nfb_nc_rxmac_deinit(internals->rxmac, internals->max_rxmac);
 
        struct rte_pci_device *pci_dev;
        int i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        PMD_INIT_LOG(DEBUG, "Close");
 
        hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        int ret;
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        rte_event_dev_close(nic->evdev);
 
 
        if (!g_pfe)
                return -1;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        pfe_eth_stop(dev);
        /* Close the device file for link status */
        pfe_eth_close_cdev(dev->data->dev_private);
 
        return 0;
 }
 
+static void
+sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
+{
+       free(dev->process_private);
+       dev->process_private = NULL;
+       dev->dev_ops = NULL;
+       dev->tx_pkt_prepare = NULL;
+       dev->tx_pkt_burst = NULL;
+       dev->rx_pkt_burst = NULL;
+}
+
 static int
 sfc_dev_close(struct rte_eth_dev *dev)
 {
 
        sfc_log_init(sa, "entry");
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+               sfc_eth_dev_secondary_clear_ops(dev);
+               return 0;
+       }
+
        sfc_adapter_lock(sa);
        switch (sa->state) {
        case SFC_ADAPTER_STARTED:
        return rc;
 }
 
-static void
-sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
-{
-       free(dev->process_private);
-       dev->process_private = NULL;
-       dev->dev_ops = NULL;
-       dev->tx_pkt_prepare = NULL;
-       dev->tx_pkt_burst = NULL;
-       dev->rx_pkt_burst = NULL;
-}
-
 static void
 sfc_register_dp(void)
 {
 static int
 sfc_eth_dev_uninit(struct rte_eth_dev *dev)
 {
-       if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-               sfc_eth_dev_secondary_clear_ops(dev);
-               return 0;
-       }
-
        sfc_dev_close(dev);
 
        return 0;
 
        uint16_t nb_rx = dev->data->nb_rx_queues;
        uint16_t nb_tx = dev->data->nb_tx_queues;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        eth_dev_stop(dev);
 
        free(internals->sze_dev_path);
 
        struct nicvf *nic = nicvf_pmd_priv(dev);
 
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        nicvf_dev_stop_cleanup(dev, true);
        nicvf_periodic_alarm_stop(nicvf_interrupt, dev);
 nicvf_eth_dev_uninit(struct rte_eth_dev *dev)
 {
        PMD_INIT_FUNC_TRACE();
-
-       if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-               nicvf_dev_close(dev);
-
+       nicvf_dev_close(dev);
        return 0;
 }
 static int
 
        struct internal_list *list;
        unsigned int i;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        internal = dev->data->dev_private;
        if (!internal)
                return 0;
        if (eth_dev == NULL)
                return 0;
 
-       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-               return rte_eth_dev_release_port(eth_dev);
-
        eth_dev_close(eth_dev);
-
        rte_eth_dev_release_port(eth_dev);
 
        return 0;
 
        struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
        PMD_INIT_LOG(DEBUG, "virtio_dev_close");
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        if (!hw->opened)
                return 0;
 
 vmxnet3_dev_close(struct rte_eth_dev *dev)
 {
        PMD_INIT_FUNC_TRACE();
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        vmxnet3_dev_stop(dev);
        vmxnet3_free_queues(dev);