[11/11] ethdev: change stop device callback to return int

Message ID 1602682146-4722-12-git-send-email-arybchenko@solarflare.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series ethdev: change device stop to return status |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/travis-robot success Travis build: passed
ci/iol-mellanox-Performance success Performance Testing PASS

Commit Message

Andrew Rybchenko Oct. 14, 2020, 1:29 p.m. UTC
  From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>

Change eth_dev_stop_t return value from void to int.
Make eth_dev_stop_t implementations across all drivers to return
negative errno values if case of error conditions.

Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 app/test/virtual_pmd.c                    |  4 ++-
 drivers/net/af_packet/rte_eth_af_packet.c |  3 +-
 drivers/net/af_xdp/rte_eth_af_xdp.c       |  3 +-
 drivers/net/ark/ark_ethdev.c              |  8 +++--
 drivers/net/atlantic/atl_ethdev.c         | 11 +++++--
 drivers/net/avp/avp_ethdev.c              |  6 ++--
 drivers/net/axgbe/axgbe_ethdev.c          |  8 +++--
 drivers/net/bnx2x/bnx2x_ethdev.c          |  6 ++--
 drivers/net/bnxt/bnxt_ethdev.c            | 17 ++++++++---
 drivers/net/bnxt/bnxt_reps.c              | 15 ++++++---
 drivers/net/bnxt/bnxt_reps.h              |  4 +--
 drivers/net/bonding/eth_bond_private.h    |  2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c    | 21 +++++++++----
 drivers/net/cxgbe/cxgbe_ethdev.c          |  6 ++--
 drivers/net/cxgbe/cxgbe_pfvf.h            |  2 +-
 drivers/net/dpaa/dpaa_ethdev.c            | 11 +++++--
 drivers/net/dpaa2/dpaa2_ethdev.c          |  6 ++--
 drivers/net/e1000/em_ethdev.c             | 15 ++++++---
 drivers/net/e1000/igb_ethdev.c            | 26 +++++++++++-----
 drivers/net/ena/ena_ethdev.c              | 14 ++++++---
 drivers/net/enetc/enetc_ethdev.c          |  9 ++++--
 drivers/net/enic/enic_ethdev.c            |  6 ++--
 drivers/net/enic/enic_vf_representor.c    |  6 ++--
 drivers/net/failsafe/failsafe_ops.c       | 23 +++++++++++---
 drivers/net/fm10k/fm10k_ethdev.c          | 11 +++++--
 drivers/net/hinic/hinic_pmd_ethdev.c      | 11 +++++--
 drivers/net/hns3/hns3_ethdev.c            | 12 ++++++--
 drivers/net/hns3/hns3_ethdev_vf.c         | 12 ++++++--
 drivers/net/i40e/i40e_ethdev.c            | 12 +++++---
 drivers/net/i40e/i40e_ethdev_vf.c         | 13 +++++---
 drivers/net/i40e/i40e_vf_representor.c    |  3 +-
 drivers/net/iavf/iavf_ethdev.c            | 13 ++++++--
 drivers/net/ice/ice_dcf_ethdev.c          |  6 ++--
 drivers/net/ice/ice_ethdev.c              | 13 +++++---
 drivers/net/igc/igc_ethdev.c              | 14 ++++++---
 drivers/net/ionic/ionic_ethdev.c          |  6 ++--
 drivers/net/ipn3ke/ipn3ke_representor.c   |  4 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 37 ++++++++++++++---------
 drivers/net/ixgbe/ixgbe_vf_representor.c  |  3 +-
 drivers/net/kni/rte_eth_kni.c             | 13 ++++++--
 drivers/net/liquidio/lio_ethdev.c         | 20 +++++++++---
 drivers/net/mlx4/mlx4.c                   |  8 +++--
 drivers/net/mlx5/mlx5.h                   |  2 +-
 drivers/net/mlx5/mlx5_trigger.c           |  4 ++-
 drivers/net/mvneta/mvneta_ethdev.c        | 15 ++++++---
 drivers/net/mvpp2/mrvl_ethdev.c           |  4 +--
 drivers/net/netvsc/hn_ethdev.c            |  8 +++--
 drivers/net/netvsc/hn_var.h               |  2 +-
 drivers/net/netvsc/hn_vf.c                | 13 ++++++--
 drivers/net/nfb/nfb_ethdev.c              |  9 ++++--
 drivers/net/nfp/nfp_net.c                 |  6 ++--
 drivers/net/null/rte_eth_null.c           |  6 ++--
 drivers/net/octeontx/octeontx_ethdev.c    | 10 +++---
 drivers/net/octeontx2/otx2_ethdev.c       |  4 ++-
 drivers/net/pcap/rte_eth_pcap.c           |  4 ++-
 drivers/net/pfe/pfe_ethdev.c              | 16 +++++++---
 drivers/net/qede/qede_ethdev.c            | 14 ++++++---
 drivers/net/ring/rte_eth_ring.c           |  8 +++--
 drivers/net/sfc/sfc_ethdev.c              |  4 ++-
 drivers/net/softnic/rte_eth_softnic.c     |  4 ++-
 drivers/net/szedata2/rte_eth_szedata2.c   | 24 +++++++++++----
 drivers/net/tap/rte_eth_tap.c             |  4 ++-
 drivers/net/thunderx/nicvf_ethdev.c       |  6 ++--
 drivers/net/vhost/rte_eth_vhost.c         | 10 ++++--
 drivers/net/virtio/virtio_ethdev.c        | 11 +++++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c      | 13 +++++---
 lib/librte_ethdev/rte_ethdev.c            |  7 +++--
 lib/librte_ethdev/rte_ethdev_driver.h     |  2 +-
 lib/librte_ethdev/rte_ethdev_trace.h      |  3 +-
 69 files changed, 461 insertions(+), 195 deletions(-)
  

Comments

Ferruh Yigit Oct. 14, 2020, 6:08 p.m. UTC | #1
On 10/14/2020 2:29 PM, Andrew Rybchenko wrote:
> From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
> 
> Change eth_dev_stop_t return value from void to int.
> Make eth_dev_stop_t implementations across all drivers to return
> negative errno values if case of error conditions.
> 
> Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>

<...>

> @@ -599,7 +599,7 @@ atl_dev_start(struct rte_eth_dev *dev)
>   /*
>    * Stop device: disable rx and tx functions to allow for reconfiguring.
>    */
> -static void
> +static int
>   atl_dev_stop(struct rte_eth_dev *dev)
>   {
>   	struct rte_eth_link link;
> @@ -639,6 +639,8 @@ atl_dev_stop(struct rte_eth_dev *dev)
>   		rte_free(intr_handle->intr_vec);
>   		intr_handle->intr_vec = NULL;
>   	}
> +
> +	return 0;
>   }
>   
>   /*
> @@ -689,6 +691,7 @@ atl_dev_close(struct rte_eth_dev *dev)
>   	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
>   	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
>   	struct aq_hw_s *hw;
> +	int ret;
>   
>   	PMD_INIT_FUNC_TRACE();
>   
> @@ -697,7 +700,9 @@ atl_dev_close(struct rte_eth_dev *dev)
>   
>   	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>   
> -	atl_dev_stop(dev);
> +	ret = atl_dev_stop(dev);
> +	if (ret != 0)
> +		return ret;
>   
 >   	atl_free_queues(dev);
 >

Not for this driver, but for all drivers,

If we return immediately on the 'stop()' error, the 'close()' function won't run 
to the end and it won't free all resources.
And according Thomas's patch, even if 'close()' dev_ops failed, the resources 
will be released and pointers will be set to null causing a possible resource leak.

What do you think don't return immediately if 'stop()' failes but store the 
error value and continue the 'close()', return that stored error at the end of 
the 'close()', briefly as following:

dev_close() {
   ...
   ret = stop()

   ... continue close ..

   return ret;
}

What do you think?


<...>

> diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
> index 4fbb7e1da0..8db7d85b04 100644
> --- a/drivers/net/failsafe/failsafe_ops.c
> +++ b/drivers/net/failsafe/failsafe_ops.c
> @@ -179,22 +179,32 @@ fs_set_queues_state_stop(struct rte_eth_dev *dev)
>   						RTE_ETH_QUEUE_STATE_STOPPED;
>   }
>   
> -static void
> +static int
>   fs_dev_stop(struct rte_eth_dev *dev)
>   {
>   	struct sub_device *sdev;
>   	uint8_t i;
> +	int ret;
>   
>   	fs_lock(dev, 0);
>   	PRIV(dev)->state = DEV_STARTED - 1;
>   	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {
> -		rte_eth_dev_stop(PORT_ID(sdev));
> +		ret = rte_eth_dev_stop(PORT_ID(sdev));
> +		if (ret != 0) {
> +			ERROR("Failed to stop device %u",
> +			      PORT_ID(sdev));
> +			PRIV(dev)->state = DEV_STARTED + 1;
> +			fs_unlock(dev, 0);
> +			return ret;
> +		}

Not sure to return after first error, or should continue the loop and return 
error afterwards?

@Gaten, what do you say?

>   		failsafe_rx_intr_uninstall_subdevice(sdev);
>   		sdev->state = DEV_STARTED - 1;
>   	}
>   	failsafe_rx_intr_uninstall(dev);
>   	fs_set_queues_state_stop(dev);
>   	fs_unlock(dev, 0);
> +
> +	return 0;
>   }
>   
>   static int
> @@ -644,8 +654,13 @@ failsafe_eth_dev_close(struct rte_eth_dev *dev)
>   
>   	fs_lock(dev, 0);
>   	failsafe_hotplug_alarm_cancel(dev);
> -	if (PRIV(dev)->state == DEV_STARTED)
> -		dev->dev_ops->dev_stop(dev);
> +	if (PRIV(dev)->state == DEV_STARTED) {
> +		ret = dev->dev_ops->dev_stop(dev);
> +		if (ret != 0) {
> +			fs_unlock(dev, 0);
> +			return ret;
> +		}
> +	}

ditto.
  
Gaëtan Rivet Oct. 15, 2020, 10:40 a.m. UTC | #2
On 14/10/20 19:08 +0100, Ferruh Yigit wrote:
> On 10/14/2020 2:29 PM, Andrew Rybchenko wrote:
> > From: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
> > 
> > Change eth_dev_stop_t return value from void to int.
> > Make eth_dev_stop_t implementations across all drivers to return
> > negative errno values if case of error conditions.
> > 
> > Signed-off-by: Ivan Ilchenko <Ivan.Ilchenko@oktetlabs.ru>
> > Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> <...>
> 
> > @@ -599,7 +599,7 @@ atl_dev_start(struct rte_eth_dev *dev)
> >   /*
> >    * Stop device: disable rx and tx functions to allow for reconfiguring.
> >    */
> > -static void
> > +static int
> >   atl_dev_stop(struct rte_eth_dev *dev)
> >   {
> >   	struct rte_eth_link link;
> > @@ -639,6 +639,8 @@ atl_dev_stop(struct rte_eth_dev *dev)
> >   		rte_free(intr_handle->intr_vec);
> >   		intr_handle->intr_vec = NULL;
> >   	}
> > +
> > +	return 0;
> >   }
> >   /*
> > @@ -689,6 +691,7 @@ atl_dev_close(struct rte_eth_dev *dev)
> >   	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
> >   	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
> >   	struct aq_hw_s *hw;
> > +	int ret;
> >   	PMD_INIT_FUNC_TRACE();
> > @@ -697,7 +700,9 @@ atl_dev_close(struct rte_eth_dev *dev)
> >   	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> > -	atl_dev_stop(dev);
> > +	ret = atl_dev_stop(dev);
> > +	if (ret != 0)
> > +		return ret;
> >   	atl_free_queues(dev);
> >
> 
> Not for this driver, but for all drivers,
> 
> If we return immediately on the 'stop()' error, the 'close()' function won't
> run to the end and it won't free all resources.
> And according Thomas's patch, even if 'close()' dev_ops failed, the
> resources will be released and pointers will be set to null causing a
> possible resource leak.
> 
> What do you think don't return immediately if 'stop()' failes but store the
> error value and continue the 'close()', return that stored error at the end
> of the 'close()', briefly as following:
> 
> dev_close() {
>   ...
>   ret = stop()
> 
>   ... continue close ..
> 
>   return ret;
> }
> 
> What do you think?
> 
> 
> <...>
> 
> > diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
> > index 4fbb7e1da0..8db7d85b04 100644
> > --- a/drivers/net/failsafe/failsafe_ops.c
> > +++ b/drivers/net/failsafe/failsafe_ops.c
> > @@ -179,22 +179,32 @@ fs_set_queues_state_stop(struct rte_eth_dev *dev)
> >   						RTE_ETH_QUEUE_STATE_STOPPED;
> >   }
> > -static void
> > +static int
> >   fs_dev_stop(struct rte_eth_dev *dev)
> >   {
> >   	struct sub_device *sdev;
> >   	uint8_t i;
> > +	int ret;
> >   	fs_lock(dev, 0);
> >   	PRIV(dev)->state = DEV_STARTED - 1;
> >   	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {
> > -		rte_eth_dev_stop(PORT_ID(sdev));
> > +		ret = rte_eth_dev_stop(PORT_ID(sdev));
> > +		if (ret != 0) {
> > +			ERROR("Failed to stop device %u",
> > +			      PORT_ID(sdev));
> > +			PRIV(dev)->state = DEV_STARTED + 1;
> > +			fs_unlock(dev, 0);
> > +			return ret;
> > +		}
> 
> Not sure to return after first error, or should continue the loop and return
> error afterwards?
> 
> @Gaten, what do you say?
> 

I've sent a v2 on this patch with some nitpicks,
but in this case, the logic to stop the loop was already there and the
change did not introduce it, it's correct IMO.

Thanks for bringing it to my attention though!

> >   		failsafe_rx_intr_uninstall_subdevice(sdev);
> >   		sdev->state = DEV_STARTED - 1;
> >   	}
> >   	failsafe_rx_intr_uninstall(dev);
> >   	fs_set_queues_state_stop(dev);
> >   	fs_unlock(dev, 0);
> > +
> > +	return 0;
> >   }
> >   static int
> > @@ -644,8 +654,13 @@ failsafe_eth_dev_close(struct rte_eth_dev *dev)
> >   	fs_lock(dev, 0);
> >   	failsafe_hotplug_alarm_cancel(dev);
> > -	if (PRIV(dev)->state == DEV_STARTED)
> > -		dev->dev_ops->dev_stop(dev);
> > +	if (PRIV(dev)->state == DEV_STARTED) {
> > +		ret = dev->dev_ops->dev_stop(dev);
> > +		if (ret != 0) {
> > +			fs_unlock(dev, 0);
> > +			return ret;
> > +		}
> > +	}
> 
> ditto.
>
  

Patch

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 4bd4d1c9ad..2c24c9b3f5 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -48,7 +48,7 @@  virtual_ethdev_start_fail(struct rte_eth_dev *eth_dev __rte_unused)
 
 	return -1;
 }
-static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
+static int  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 {
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
@@ -60,6 +60,8 @@  static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 
 	while (rte_ring_dequeue(prv->tx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 25876224f8..cb1c39b027 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -272,7 +272,7 @@  eth_dev_start(struct rte_eth_dev *dev)
 /*
  * This function gets called when the current port gets stopped.
  */
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	unsigned i;
@@ -296,6 +296,7 @@  eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	return 0;
 }
 
 static int
diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c
index 0562e58696..1c1e3cadd6 100644
--- a/drivers/net/af_xdp/rte_eth_af_xdp.c
+++ b/drivers/net/af_xdp/rte_eth_af_xdp.c
@@ -599,10 +599,11 @@  eth_dev_start(struct rte_eth_dev *dev)
 }
 
 /* This function gets called when the current port gets stopped. */
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	return 0;
 }
 
 /* Find ethdev in list */
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index e3b1347769..f86a87fb47 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -29,7 +29,7 @@  static int ark_config_device(struct rte_eth_dev *dev);
 static int eth_ark_dev_uninit(struct rte_eth_dev *eth_dev);
 static int eth_ark_dev_configure(struct rte_eth_dev *dev);
 static int eth_ark_dev_start(struct rte_eth_dev *dev);
-static void eth_ark_dev_stop(struct rte_eth_dev *dev);
+static int eth_ark_dev_stop(struct rte_eth_dev *dev);
 static int eth_ark_dev_close(struct rte_eth_dev *dev);
 static int eth_ark_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
@@ -584,7 +584,7 @@  eth_ark_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 eth_ark_dev_stop(struct rte_eth_dev *dev)
 {
 	uint16_t i;
@@ -593,7 +593,7 @@  eth_ark_dev_stop(struct rte_eth_dev *dev)
 	struct ark_mpu_t *mpu;
 
 	if (ark->started == 0)
-		return;
+		return 0;
 	ark->started = 0;
 
 	/* Stop the extension first */
@@ -672,6 +672,8 @@  eth_ark_dev_stop(struct rte_eth_dev *dev)
 		ark_pktchkr_dump_stats(ark->pc);
 		ark_pktchkr_stop(ark->pc);
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 2217511ca0..890848b4c4 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -17,7 +17,7 @@ 
 static int eth_atl_dev_init(struct rte_eth_dev *eth_dev);
 static int  atl_dev_configure(struct rte_eth_dev *dev);
 static int  atl_dev_start(struct rte_eth_dev *dev);
-static void atl_dev_stop(struct rte_eth_dev *dev);
+static int atl_dev_stop(struct rte_eth_dev *dev);
 static int  atl_dev_set_link_up(struct rte_eth_dev *dev);
 static int  atl_dev_set_link_down(struct rte_eth_dev *dev);
 static int  atl_dev_close(struct rte_eth_dev *dev);
@@ -599,7 +599,7 @@  atl_dev_start(struct rte_eth_dev *dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-static void
+static int
 atl_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
@@ -639,6 +639,8 @@  atl_dev_stop(struct rte_eth_dev *dev)
 		rte_free(intr_handle->intr_vec);
 		intr_handle->intr_vec = NULL;
 	}
+
+	return 0;
 }
 
 /*
@@ -689,6 +691,7 @@  atl_dev_close(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct aq_hw_s *hw;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -697,7 +700,9 @@  atl_dev_close(struct rte_eth_dev *dev)
 
 	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	atl_dev_stop(dev);
+	ret = atl_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	atl_free_queues(dev);
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index 95fdb57451..67f16623c5 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -37,7 +37,7 @@  static int avp_dev_create(struct rte_pci_device *pci_dev,
 
 static int avp_dev_configure(struct rte_eth_dev *dev);
 static int avp_dev_start(struct rte_eth_dev *dev);
-static void avp_dev_stop(struct rte_eth_dev *dev);
+static int avp_dev_stop(struct rte_eth_dev *dev);
 static int avp_dev_close(struct rte_eth_dev *dev);
 static int avp_dev_info_get(struct rte_eth_dev *dev,
 			    struct rte_eth_dev_info *dev_info);
@@ -2075,7 +2075,7 @@  avp_dev_start(struct rte_eth_dev *eth_dev)
 	return ret;
 }
 
-static void
+static int
 avp_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
@@ -2084,6 +2084,7 @@  avp_dev_stop(struct rte_eth_dev *eth_dev)
 	rte_spinlock_lock(&avp->lock);
 	if (avp->flags & AVP_F_DETACHED) {
 		PMD_DRV_LOG(ERR, "Operation not supported during VM live migration\n");
+		ret = -ENOTSUP;
 		goto unlock;
 	}
 
@@ -2099,6 +2100,7 @@  avp_dev_stop(struct rte_eth_dev *eth_dev)
 
 unlock:
 	rte_spinlock_unlock(&avp->lock);
+	return ret;
 }
 
 static int
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index cf085487cc..ce30a4f22c 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -13,7 +13,7 @@ 
 static int eth_axgbe_dev_init(struct rte_eth_dev *eth_dev);
 static int  axgbe_dev_configure(struct rte_eth_dev *dev);
 static int  axgbe_dev_start(struct rte_eth_dev *dev);
-static void axgbe_dev_stop(struct rte_eth_dev *dev);
+static int  axgbe_dev_stop(struct rte_eth_dev *dev);
 static void axgbe_dev_interrupt_handler(void *param);
 static int axgbe_dev_close(struct rte_eth_dev *dev);
 static int axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
@@ -386,7 +386,7 @@  axgbe_dev_start(struct rte_eth_dev *dev)
 }
 
 /* Stop device: disable rx and tx functions to allow for reconfiguring. */
-static void
+static int
 axgbe_dev_stop(struct rte_eth_dev *dev)
 {
 	struct axgbe_port *pdata = dev->data->dev_private;
@@ -396,7 +396,7 @@  axgbe_dev_stop(struct rte_eth_dev *dev)
 	rte_intr_disable(&pdata->pci_dev->intr_handle);
 
 	if (rte_bit_relaxed_get32(AXGBE_STOPPED, &pdata->dev_state))
-		return;
+		return 0;
 
 	rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state);
 	axgbe_dev_disable_tx(dev);
@@ -406,6 +406,8 @@  axgbe_dev_stop(struct rte_eth_dev *dev)
 	pdata->hw_if.exit(pdata);
 	memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
 	rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 40225b2f44..5704afa749 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -247,7 +247,7 @@  bnx2x_dev_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static void
+static int
 bnx2x_dev_stop(struct rte_eth_dev *dev)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
@@ -274,10 +274,10 @@  bnx2x_dev_stop(struct rte_eth_dev *dev)
 	ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
 	if (ret) {
 		PMD_DRV_LOG(DEBUG, sc, "bnx2x_nic_unload failed (%d)", ret);
-		return;
+		return ret;
 	}
 
-	return;
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index b4654ec6af..ea0eb1383a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1345,12 +1345,13 @@  static void bnxt_free_switch_domain(struct bnxt *bp)
 }
 
 /* Unload the driver, release resources */
-static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+static int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct rte_eth_link link;
+	int ret;
 
 	eth_dev->data->dev_started = 0;
 	eth_dev->data->scattered_rx = 0;
@@ -1365,7 +1366,9 @@  static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	rte_intr_disable(intr_handle);
 
 	/* Stop the child representors for this device */
-	bnxt_rep_stop_all(bp);
+	ret = bnxt_rep_stop_all(bp);
+	if (ret != 0)
+		return ret;
 
 	/* delete the bnxt ULP port details */
 	bnxt_ulp_port_deinit(bp);
@@ -1406,11 +1409,14 @@  static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	/* All filters are deleted on a port stop. */
 	if (BNXT_FLOW_XSTATS_EN(bp))
 		bp->flow_stat->flow_count = 0;
+
+	return 0;
 }
 
 static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -1420,8 +1426,11 @@  static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
 	rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
 	bnxt_cancel_fc_thread(bp);
 
-	if (eth_dev->data->dev_started)
-		bnxt_dev_stop_op(eth_dev);
+	if (eth_dev->data->dev_started) {
+		ret = bnxt_dev_stop_op(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	bnxt_free_switch_domain(bp);
 
diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index 74a76fce57..fb171245df 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -476,7 +476,7 @@  static int bnxt_vfr_free(struct bnxt_representor *vfr)
 	return rc;
 }
 
-void bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev)
+int bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt_representor *vfr_bp = eth_dev->data->dev_private;
 
@@ -492,6 +492,8 @@  void bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 
 	bnxt_rep_free_rx_mbufs(vfr_bp);
+
+	return 0;
 }
 
 int bnxt_rep_dev_close_op(struct rte_eth_dev *eth_dev)
@@ -808,19 +810,24 @@  int bnxt_rep_stats_reset_op(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-void bnxt_rep_stop_all(struct bnxt *bp)
+int bnxt_rep_stop_all(struct bnxt *bp)
 {
 	uint16_t vf_id;
 	struct rte_eth_dev *rep_eth_dev;
+	int ret;
 
 	/* No vfrep ports just exit */
 	if (!bp->rep_info)
-		return;
+		return 0;
 
 	for (vf_id = 0; vf_id < BNXT_MAX_VF_REPS; vf_id++) {
 		rep_eth_dev = bp->rep_info[vf_id].vfr_eth_dev;
 		if (!rep_eth_dev)
 			continue;
-		bnxt_rep_dev_stop_op(rep_eth_dev);
+		ret = bnxt_rep_dev_stop_op(rep_eth_dev);
+		if (ret != 0)
+			return ret;
 	}
+
+	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_reps.h b/drivers/net/bnxt/bnxt_reps.h
index a019530094..916769ca67 100644
--- a/drivers/net/bnxt/bnxt_reps.h
+++ b/drivers/net/bnxt/bnxt_reps.h
@@ -44,10 +44,10 @@  int bnxt_rep_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 				  tx_conf);
 void bnxt_rep_rx_queue_release_op(void *rx_queue);
 void bnxt_rep_tx_queue_release_op(void *tx_queue);
-void bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev);
+int  bnxt_rep_dev_stop_op(struct rte_eth_dev *eth_dev);
 int bnxt_rep_dev_close_op(struct rte_eth_dev *eth_dev);
 int bnxt_rep_stats_get_op(struct rte_eth_dev *eth_dev,
 			     struct rte_eth_stats *stats);
 int bnxt_rep_stats_reset_op(struct rte_eth_dev *eth_dev);
-void bnxt_rep_stop_all(struct bnxt *bp);
+int bnxt_rep_stop_all(struct bnxt *bp);
 #endif /* _BNXT_REPS_H_ */
diff --git a/drivers/net/bonding/eth_bond_private.h b/drivers/net/bonding/eth_bond_private.h
index 62e3a9dbf3..8f198bd50e 100644
--- a/drivers/net/bonding/eth_bond_private.h
+++ b/drivers/net/bonding/eth_bond_private.h
@@ -316,7 +316,7 @@  bond_tlb_enable(struct bond_dev_private *internals);
 void
 bond_tlb_activate_slave(struct bond_dev_private *internals);
 
-void
+int
 bond_ethdev_stop(struct rte_eth_dev *eth_dev);
 
 int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 6cb03d40d7..3c4d8b5070 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1695,11 +1695,9 @@  slave_configure(struct rte_eth_dev *bonded_eth_dev,
 
 	/* Stop slave */
 	errval = rte_eth_dev_stop(slave_eth_dev->data->port_id);
-	if (errval != 0) {
+	if (errval != 0)
 		RTE_BOND_LOG(ERR, "rte_eth_dev_stop: port %u, err (%d)",
 			     slave_eth_dev->data->port_id, errval);
-		return errval;
-	}
 
 	/* Enable interrupts on slave device if supported */
 	if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
@@ -2051,11 +2049,12 @@  bond_ethdev_free_queues(struct rte_eth_dev *dev)
 	}
 }
 
-void
+int
 bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct bond_dev_private *internals = eth_dev->data->dev_private;
 	uint16_t i;
+	int ret;
 
 	if (internals->mode == BONDING_MODE_8023AD) {
 		struct port *port;
@@ -2094,10 +2093,17 @@  bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 				internals->active_slave_count, slave_id) !=
 						internals->active_slave_count) {
 			internals->slaves[i].last_link_status = 0;
-			rte_eth_dev_stop(slave_id);
+			ret = rte_eth_dev_stop(slave_id);
+			if (ret != 0) {
+				RTE_BOND_LOG(ERR, "Failed to stop device on port %u",
+					     slave_id);
+				return ret;
+			}
 			deactivate_slave(eth_dev, slave_id);
 		}
 	}
+
+	return 0;
 }
 
 int
@@ -3430,6 +3436,7 @@  bond_remove(struct rte_vdev_device *dev)
 	struct rte_eth_dev *eth_dev;
 	struct bond_dev_private *internals;
 	const char *name;
+	int ret;
 
 	if (!dev)
 		return -EINVAL;
@@ -3452,7 +3459,9 @@  bond_remove(struct rte_vdev_device *dev)
 		return -EBUSY;
 
 	if (eth_dev->data->dev_started == 1) {
-		bond_ethdev_stop(eth_dev);
+		ret = bond_ethdev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
 		bond_ethdev_close(eth_dev);
 	}
 	rte_eth_dev_release_port(eth_dev);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 16beb2d435..29c061e505 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -416,7 +416,7 @@  int cxgbe_dev_start(struct rte_eth_dev *eth_dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-void cxgbe_dev_stop(struct rte_eth_dev *eth_dev)
+int cxgbe_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
@@ -424,7 +424,7 @@  void cxgbe_dev_stop(struct rte_eth_dev *eth_dev)
 	CXGBE_FUNC_TRACE();
 
 	if (!(adapter->flags & FULL_INIT_DONE))
-		return;
+		return 0;
 
 	cxgbe_down(pi);
 
@@ -434,6 +434,8 @@  void cxgbe_dev_stop(struct rte_eth_dev *eth_dev)
 	 */
 	t4_sge_eth_clear_queues(pi);
 	eth_dev->data->scattered_rx = 0;
+
+	return 0;
 }
 
 int cxgbe_dev_configure(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 69d91639e9..801d6995d1 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -18,7 +18,7 @@ 
 
 void cxgbe_dev_rx_queue_release(void *q);
 void cxgbe_dev_tx_queue_release(void *q);
-void cxgbe_dev_stop(struct rte_eth_dev *eth_dev);
+int cxgbe_dev_stop(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_close(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 		       struct rte_eth_dev_info *device_info);
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index af47c196ae..583e689760 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -415,7 +415,7 @@  static int dpaa_eth_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void dpaa_eth_dev_stop(struct rte_eth_dev *dev)
+static int dpaa_eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct fman_if *fif = dev->process_private;
 
@@ -424,6 +424,8 @@  static void dpaa_eth_dev_stop(struct rte_eth_dev *dev)
 	if (!fif->is_shared_mac)
 		fman_if_disable_rx(fif);
 	dev->tx_pkt_burst = dpaa_eth_tx_drop_all;
+
+	return 0;
 }
 
 static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
@@ -436,6 +438,7 @@  static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	struct rte_eth_link *link = &dev->data->dev_link;
 	struct dpaa_if *dpaa_intf = dev->data->dev_private;
 	int loop;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -457,7 +460,9 @@  static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	intr_handle = &dpaa_dev->intr_handle;
 	__fif = container_of(fif, struct __fman_if, __if);
 
-	dpaa_eth_dev_stop(dev);
+	ret = dpaa_eth_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	/* Reset link to autoneg */
 	if (link->link_status && !link->link_autoneg)
@@ -1293,7 +1298,7 @@  static int dpaa_link_down(struct rte_eth_dev *dev)
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		dpaa_update_link_status(__fif->node_name, ETH_LINK_DOWN);
 	else
-		dpaa_eth_dev_stop(dev);
+		return dpaa_eth_dev_stop(dev);
 	return 0;
 }
 
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index d8624514df..3a17d54e2e 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1195,7 +1195,7 @@  dpaa2_dev_start(struct rte_eth_dev *dev)
  *  This routine disables all traffic on the adapter by issuing a
  *  global reset on the MAC.
  */
-static void
+static int
 dpaa2_dev_stop(struct rte_eth_dev *dev)
 {
 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
@@ -1227,12 +1227,14 @@  dpaa2_dev_stop(struct rte_eth_dev *dev)
 	if (ret) {
 		DPAA2_PMD_ERR("Failure (ret %d) in disabling dpni %d dev",
 			      ret, priv->hw_id);
-		return;
+		return ret;
 	}
 
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_eth_linkstatus_set(dev, &link);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d050eb478a..27da5a67c2 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -33,7 +33,7 @@ 
 
 static int eth_em_configure(struct rte_eth_dev *dev);
 static int eth_em_start(struct rte_eth_dev *dev);
-static void eth_em_stop(struct rte_eth_dev *dev);
+static int eth_em_stop(struct rte_eth_dev *dev);
 static int eth_em_close(struct rte_eth_dev *dev);
 static int eth_em_promiscuous_enable(struct rte_eth_dev *dev);
 static int eth_em_promiscuous_disable(struct rte_eth_dev *dev);
@@ -533,7 +533,9 @@  eth_em_start(struct rte_eth_dev *dev)
 
 	PMD_INIT_FUNC_TRACE();
 
-	eth_em_stop(dev);
+	ret = eth_em_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	e1000_power_up_phy(hw);
 
@@ -709,7 +711,7 @@  eth_em_start(struct rte_eth_dev *dev)
  *  global reset on the MAC.
  *
  **********************************************************************/
-static void
+static int
 eth_em_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
@@ -751,6 +753,8 @@  eth_em_stop(struct rte_eth_dev *dev)
 		rte_free(intr_handle->intr_vec);
 		intr_handle->intr_vec = NULL;
 	}
+
+	return 0;
 }
 
 static int
@@ -761,11 +765,14 @@  eth_em_close(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	eth_em_stop(dev);
+	ret = eth_em_stop(dev);
+	if (ret != 0)
+		return ret;
 	adapter->stopped = 1;
 	em_dev_free_queues(dev);
 	e1000_phy_hw_reset(hw);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index cb3d97e2a3..ab55f2a90d 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -74,7 +74,7 @@ 
 
 static int  eth_igb_configure(struct rte_eth_dev *dev);
 static int  eth_igb_start(struct rte_eth_dev *dev);
-static void eth_igb_stop(struct rte_eth_dev *dev);
+static int  eth_igb_stop(struct rte_eth_dev *dev);
 static int  eth_igb_dev_set_link_up(struct rte_eth_dev *dev);
 static int  eth_igb_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_igb_close(struct rte_eth_dev *dev);
@@ -154,7 +154,7 @@  static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 static void igbvf_intr_disable(struct e1000_hw *hw);
 static int igbvf_dev_configure(struct rte_eth_dev *dev);
 static int igbvf_dev_start(struct rte_eth_dev *dev);
-static void igbvf_dev_stop(struct rte_eth_dev *dev);
+static int igbvf_dev_stop(struct rte_eth_dev *dev);
 static int igbvf_dev_close(struct rte_eth_dev *dev);
 static int igbvf_promiscuous_enable(struct rte_eth_dev *dev);
 static int igbvf_promiscuous_disable(struct rte_eth_dev *dev);
@@ -1441,7 +1441,7 @@  eth_igb_start(struct rte_eth_dev *dev)
  *  global reset on the MAC.
  *
  **********************************************************************/
-static void
+static int
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1452,7 +1452,7 @@  eth_igb_stop(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE(dev->data->dev_private);
 
 	if (adapter->stopped)
-		return;
+		return 0;
 
 	eth_igb_rxtx_control(dev, false);
 
@@ -1497,6 +1497,8 @@  eth_igb_stop(struct rte_eth_dev *dev)
 	}
 
 	adapter->stopped = true;
+
+	return 0;
 }
 
 static int
@@ -1534,11 +1536,14 @@  eth_igb_close(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct e1000_filter_info *filter_info =
 		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	eth_igb_stop(dev);
+	ret = eth_igb_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	e1000_phy_hw_reset(hw);
 	igb_release_manageability(hw);
@@ -3340,7 +3345,7 @@  igbvf_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 igbvf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
@@ -3349,7 +3354,7 @@  igbvf_dev_stop(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE(dev->data->dev_private);
 
 	if (adapter->stopped)
-		return;
+		return 0;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -3374,6 +3379,8 @@  igbvf_dev_stop(struct rte_eth_dev *dev)
 	}
 
 	adapter->stopped = true;
+
+	return 0;
 }
 
 static int
@@ -3382,6 +3389,7 @@  igbvf_dev_close(struct rte_eth_dev *dev)
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_ether_addr addr;
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -3390,7 +3398,9 @@  igbvf_dev_close(struct rte_eth_dev *dev)
 
 	e1000_reset_hw(hw);
 
-	igbvf_dev_stop(dev);
+	ret = igbvf_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	igb_dev_free_queues(dev);
 
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index d32fa43837..775861b44c 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -198,7 +198,7 @@  static void ena_init_rings(struct ena_adapter *adapter,
 			   bool disable_meta_caching);
 static int ena_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int ena_start(struct rte_eth_dev *dev);
-static void ena_stop(struct rte_eth_dev *dev);
+static int ena_stop(struct rte_eth_dev *dev);
 static int ena_close(struct rte_eth_dev *dev);
 static int ena_dev_reset(struct rte_eth_dev *dev);
 static int ena_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
@@ -505,12 +505,16 @@  static int ena_close(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct ena_adapter *adapter = dev->data->dev_private;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	if (adapter->state == ENA_ADAPTER_STATE_RUNNING)
-		ena_stop(dev);
+	if (adapter->state == ENA_ADAPTER_STATE_RUNNING) {
+		ret = ena_stop(dev);
+		if (ret != 0)
+			return ret;
+	}
 	adapter->state = ENA_ADAPTER_STATE_CLOSED;
 
 	ena_rx_queue_release_all(dev);
@@ -1100,7 +1104,7 @@  static int ena_start(struct rte_eth_dev *dev)
 	return rc;
 }
 
-static void ena_stop(struct rte_eth_dev *dev)
+static int ena_stop(struct rte_eth_dev *dev)
 {
 	struct ena_adapter *adapter = dev->data->dev_private;
 	struct ena_com_dev *ena_dev = &adapter->ena_dev;
@@ -1118,6 +1122,8 @@  static void ena_stop(struct rte_eth_dev *dev)
 
 	++adapter->dev_stats.dev_stop;
 	adapter->state = ENA_ADAPTER_STATE_STOPPED;
+
+	return 0;
 }
 
 static int ena_create_io_queue(struct ena_ring *ring)
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index b3dec7e64d..1ae83daee5 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -45,7 +45,7 @@  enetc_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 enetc_dev_stop(struct rte_eth_dev *dev)
 {
 	struct enetc_eth_hw *hw =
@@ -61,6 +61,8 @@  enetc_dev_stop(struct rte_eth_dev *dev)
 	val = enetc_port_rd(enetc_hw, ENETC_PM0_CMD_CFG);
 	enetc_port_wr(enetc_hw, ENETC_PM0_CMD_CFG,
 		      val & (~(ENETC_PM0_TX_EN | ENETC_PM0_RX_EN)));
+
+	return 0;
 }
 
 static const uint32_t *
@@ -549,12 +551,15 @@  static int
 enetc_dev_close(struct rte_eth_dev *dev)
 {
 	uint16_t i;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	enetc_dev_stop(dev);
+	ret = enetc_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		enetc_rx_queue_release(dev->data->rx_queues[i]);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 60ee5e01de..4a34c0ef83 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -428,19 +428,21 @@  static int enicpmd_dev_start(struct rte_eth_dev *eth_dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-static void enicpmd_dev_stop(struct rte_eth_dev *eth_dev)
+static int enicpmd_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct rte_eth_link link;
 	struct enic *enic = pmd_priv(eth_dev);
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return;
+		return 0;
 
 	ENICPMD_FUNC_TRACE();
 	enic_disable(enic);
 
 	memset(&link, 0, sizeof(link));
 	rte_eth_linkstatus_set(eth_dev, &link);
+
+	return 0;
 }
 
 /*
diff --git a/drivers/net/enic/enic_vf_representor.c b/drivers/net/enic/enic_vf_representor.c
index 169c611a68..984a754e35 100644
--- a/drivers/net/enic/enic_vf_representor.c
+++ b/drivers/net/enic/enic_vf_representor.c
@@ -242,7 +242,7 @@  static int enic_vf_dev_start(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-static void enic_vf_dev_stop(struct rte_eth_dev *eth_dev)
+static int enic_vf_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct enic_vf_representor *vf;
 	struct vnic_rq *rq;
@@ -250,7 +250,7 @@  static void enic_vf_dev_stop(struct rte_eth_dev *eth_dev)
 
 	ENICPMD_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return;
+		return 0;
 	/* Undo dev_start. Disable/clean WQ */
 	vf = eth_dev->data->dev_private;
 	pf = vf->pf;
@@ -271,6 +271,8 @@  static void enic_vf_dev_stop(struct rte_eth_dev *eth_dev)
 	eth_dev->data->rx_queue_state[0] = RTE_ETH_QUEUE_STATE_STOPPED;
 	/* Clean up representor flowman */
 	enic_fm_destroy(&vf->enic);
+
+	return 0;
 }
 
 /*
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 4fbb7e1da0..8db7d85b04 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -179,22 +179,32 @@  fs_set_queues_state_stop(struct rte_eth_dev *dev)
 						RTE_ETH_QUEUE_STATE_STOPPED;
 }
 
-static void
+static int
 fs_dev_stop(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
 	PRIV(dev)->state = DEV_STARTED - 1;
 	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {
-		rte_eth_dev_stop(PORT_ID(sdev));
+		ret = rte_eth_dev_stop(PORT_ID(sdev));
+		if (ret != 0) {
+			ERROR("Failed to stop device %u",
+			      PORT_ID(sdev));
+			PRIV(dev)->state = DEV_STARTED + 1;
+			fs_unlock(dev, 0);
+			return ret;
+		}
 		failsafe_rx_intr_uninstall_subdevice(sdev);
 		sdev->state = DEV_STARTED - 1;
 	}
 	failsafe_rx_intr_uninstall(dev);
 	fs_set_queues_state_stop(dev);
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
@@ -644,8 +654,13 @@  failsafe_eth_dev_close(struct rte_eth_dev *dev)
 
 	fs_lock(dev, 0);
 	failsafe_hotplug_alarm_cancel(dev);
-	if (PRIV(dev)->state == DEV_STARTED)
-		dev->dev_ops->dev_stop(dev);
+	if (PRIV(dev)->state == DEV_STARTED) {
+		ret = dev->dev_ops->dev_stop(dev);
+		if (ret != 0) {
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	PRIV(dev)->state = DEV_ACTIVE - 1;
 	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
 		DEBUG("Closing sub_device %d", i);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index c4a6fdf7f0..41eb0b9691 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1152,7 +1152,7 @@  fm10k_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 fm10k_dev_stop(struct rte_eth_dev *dev)
 {
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1187,6 +1187,8 @@  fm10k_dev_stop(struct rte_eth_dev *dev)
 	rte_intr_efd_disable(intr_handle);
 	rte_free(intr_handle->intr_vec);
 	intr_handle->intr_vec = NULL;
+
+	return 0;
 }
 
 static void
@@ -2785,6 +2787,7 @@  fm10k_dev_close(struct rte_eth_dev *dev)
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pdev->intr_handle;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
@@ -2800,7 +2803,11 @@  fm10k_dev_close(struct rte_eth_dev *dev)
 
 	/* Stop mailbox service first */
 	fm10k_close_mbx_service(hw);
-	fm10k_dev_stop(dev);
+
+	ret = fm10k_dev_stop(dev);
+	if (ret != 0)
+		return ret;
+
 	fm10k_dev_queue_release(dev);
 	fm10k_stop_hw(hw);
 
diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c
index 466c8362b9..41334cd622 100644
--- a/drivers/net/hinic/hinic_pmd_ethdev.c
+++ b/drivers/net/hinic/hinic_pmd_ethdev.c
@@ -1177,7 +1177,7 @@  static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void hinic_dev_stop(struct rte_eth_dev *dev)
+static int hinic_dev_stop(struct rte_eth_dev *dev)
 {
 	int rc;
 	char *name;
@@ -1192,7 +1192,7 @@  static void hinic_dev_stop(struct rte_eth_dev *dev)
 	if (!rte_bit_relaxed_test_and_clear32(HINIC_DEV_START,
 					      &nic_dev->dev_status)) {
 		PMD_DRV_LOG(INFO, "Device %s already stopped", name);
-		return;
+		return 0;
 	}
 
 	/* just stop phy port and vport */
@@ -1227,6 +1227,8 @@  static void hinic_dev_stop(struct rte_eth_dev *dev)
 	/* free mbuf */
 	hinic_free_all_rx_mbuf(dev);
 	hinic_free_all_tx_mbuf(dev);
+
+	return 0;
 }
 
 static void hinic_disable_interrupt(struct rte_eth_dev *dev)
@@ -2968,6 +2970,7 @@  static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev)
 static int hinic_dev_close(struct rte_eth_dev *dev)
 {
 	struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -2980,7 +2983,9 @@  static int hinic_dev_close(struct rte_eth_dev *dev)
 	}
 
 	/* stop device first */
-	hinic_dev_stop(dev);
+	ret = hinic_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	/* rx_cqe, rx_info */
 	hinic_free_all_rx_resources(dev);
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index ce5bae538d..051546a1ce 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -4990,7 +4990,7 @@  hns3_unmap_rx_interrupt(struct rte_eth_dev *dev)
 	}
 }
 
-static void
+static int
 hns3_dev_stop(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
@@ -5017,6 +5017,8 @@  hns3_dev_stop(struct rte_eth_dev *dev)
 	hns3_rx_scattered_reset(dev);
 	rte_eal_alarm_cancel(hns3_service_handler, dev);
 	rte_spinlock_unlock(&hw->lock);
+
+	return 0;
 }
 
 static int
@@ -5024,6 +5026,7 @@  hns3_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
 		rte_free(eth_dev->process_private);
@@ -5031,8 +5034,11 @@  hns3_dev_close(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	if (hw->adapter_state == HNS3_NIC_STARTED)
-		hns3_dev_stop(eth_dev);
+	if (hw->adapter_state == HNS3_NIC_STARTED) {
+		ret = hns3_dev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	hw->adapter_state = HNS3_NIC_CLOSING;
 	hns3_reset_abort(hns);
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 1a19c0e6e6..29cb326f67 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -1945,7 +1945,7 @@  hns3vf_unmap_rx_interrupt(struct rte_eth_dev *dev)
 	}
 }
 
-static void
+static int
 hns3vf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
@@ -1972,6 +1972,8 @@  hns3vf_dev_stop(struct rte_eth_dev *dev)
 	hns3_rx_scattered_reset(dev);
 	rte_eal_alarm_cancel(hns3vf_service_handler, dev);
 	rte_spinlock_unlock(&hw->lock);
+
+	return 0;
 }
 
 static int
@@ -1979,12 +1981,16 @@  hns3vf_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	if (hw->adapter_state == HNS3_NIC_STARTED)
-		hns3vf_dev_stop(eth_dev);
+	if (hw->adapter_state == HNS3_NIC_STARTED) {
+		ret = hns3vf_dev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	hw->adapter_state = HNS3_NIC_CLOSING;
 	hns3_reset_abort(hns);
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 943cfe71dc..de8d0db31c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -224,7 +224,7 @@  static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
 static int i40e_dev_start(struct rte_eth_dev *dev);
-static void i40e_dev_stop(struct rte_eth_dev *dev);
+static int i40e_dev_stop(struct rte_eth_dev *dev);
 static int i40e_dev_close(struct rte_eth_dev *dev);
 static int  i40e_dev_reset(struct rte_eth_dev *dev);
 static int i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
@@ -2542,7 +2542,7 @@  i40e_dev_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static void
+static int
 i40e_dev_stop(struct rte_eth_dev *dev)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -2553,7 +2553,7 @@  i40e_dev_stop(struct rte_eth_dev *dev)
 	int i;
 
 	if (hw->adapter_stopped == 1)
-		return;
+		return 0;
 
 	if (dev->data->dev_conf.intr_conf.rxq == 0) {
 		rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev);
@@ -2601,6 +2601,8 @@  i40e_dev_stop(struct rte_eth_dev *dev)
 	hw->adapter_stopped = 1;
 
 	pf->adapter->rss_reta_updated = 0;
+
+	return 0;
 }
 
 static int
@@ -2628,7 +2630,9 @@  i40e_dev_close(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
 
 
-	i40e_dev_stop(dev);
+	ret = i40e_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	/* Remove all mirror rules */
 	while ((p_mirror = TAILQ_FIRST(&pf->mirror_list))) {
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 4d6510d1ff..60999bcf55 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -74,7 +74,7 @@  enum i40evf_aq_result {
 
 static int i40evf_dev_configure(struct rte_eth_dev *dev);
 static int i40evf_dev_start(struct rte_eth_dev *dev);
-static void i40evf_dev_stop(struct rte_eth_dev *dev);
+static int i40evf_dev_stop(struct rte_eth_dev *dev);
 static int i40evf_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
 static int i40evf_dev_link_update(struct rte_eth_dev *dev,
@@ -2176,7 +2176,7 @@  i40evf_dev_start(struct rte_eth_dev *dev)
 	return -1;
 }
 
-static void
+static int
 i40evf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
@@ -2190,7 +2190,7 @@  i40evf_dev_stop(struct rte_eth_dev *dev)
 		rte_intr_disable(intr_handle);
 
 	if (hw->adapter_stopped == 1)
-		return;
+		return 0;
 	i40evf_stop_queues(dev);
 	i40evf_disable_queues_intr(dev);
 	i40e_dev_clear_queues(dev);
@@ -2208,6 +2208,7 @@  i40evf_dev_stop(struct rte_eth_dev *dev)
 				FALSE);
 	hw->adapter_stopped = 1;
 
+	return 0;
 }
 
 static int
@@ -2401,11 +2402,15 @@  i40evf_dev_close(struct rte_eth_dev *dev)
 {
 	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);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	i40evf_dev_stop(dev);
+	ret = i40evf_dev_stop(dev);
+	if (ret != 0)
+		return ret;
+
 	i40e_dev_free_queues(dev);
 	/*
 	 * disable promiscuous mode before reset vf
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index f09d4d8798..791c050b8c 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -118,9 +118,10 @@  i40e_vf_representor_dev_start(__rte_unused struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 i40e_vf_representor_dev_stop(__rte_unused struct rte_eth_dev *dev)
 {
+	return 0;
 }
 
 static int
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index f5e6e852ae..321b80c4ba 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -31,7 +31,7 @@ 
 
 static int iavf_dev_configure(struct rte_eth_dev *dev);
 static int iavf_dev_start(struct rte_eth_dev *dev);
-static void iavf_dev_stop(struct rte_eth_dev *dev);
+static int iavf_dev_stop(struct rte_eth_dev *dev);
 static int iavf_dev_close(struct rte_eth_dev *dev);
 static int iavf_dev_reset(struct rte_eth_dev *dev);
 static int iavf_dev_info_get(struct rte_eth_dev *dev,
@@ -531,7 +531,7 @@  iavf_dev_start(struct rte_eth_dev *dev)
 	return -1;
 }
 
-static void
+static int
 iavf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -542,7 +542,7 @@  iavf_dev_stop(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	if (adapter->stopped == 1)
-		return;
+		return 0;
 
 	iavf_stop_queues(dev);
 
@@ -562,6 +562,8 @@  iavf_dev_stop(struct rte_eth_dev *dev)
 				  false);
 
 	adapter->stopped = 1;
+
+	return 0;
 }
 
 static int
@@ -1499,11 +1501,16 @@  iavf_dev_close(struct rte_eth_dev *dev)
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
 	iavf_dev_stop(dev);
+	ret = iavf_dev_stop(dev);
+	if (ret != 0)
+		return ret;
+
 	iavf_flow_flush(dev, NULL);
 	iavf_flow_uninit(adapter);
 
diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index 33dd0c44f2..047926dab2 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -589,7 +589,7 @@  ice_dcf_stop_queues(struct rte_eth_dev *dev)
 	}
 }
 
-static void
+static int
 ice_dcf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
@@ -598,7 +598,7 @@  ice_dcf_dev_stop(struct rte_eth_dev *dev)
 
 	if (ad->pf.adapter_stopped == 1) {
 		PMD_DRV_LOG(DEBUG, "Port is already stopped");
-		return;
+		return 0;
 	}
 
 	ice_dcf_stop_queues(dev);
@@ -612,6 +612,8 @@  ice_dcf_dev_stop(struct rte_eth_dev *dev)
 	ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw, false);
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	ad->pf.adapter_stopped = 1;
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 0056da78a5..bfc6ce42f3 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -76,7 +76,7 @@  static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = {
 
 static int ice_dev_configure(struct rte_eth_dev *dev);
 static int ice_dev_start(struct rte_eth_dev *dev);
-static void ice_dev_stop(struct rte_eth_dev *dev);
+static int ice_dev_stop(struct rte_eth_dev *dev);
 static int ice_dev_close(struct rte_eth_dev *dev);
 static int ice_dev_reset(struct rte_eth_dev *dev);
 static int ice_dev_info_get(struct rte_eth_dev *dev,
@@ -2331,7 +2331,7 @@  ice_vsi_disable_queues_intr(struct ice_vsi *vsi)
 		ICE_WRITE_REG(hw, GLINT_DYN_CTL(0), GLINT_DYN_CTL_WB_ON_ITR_M);
 }
 
-static void
+static int
 ice_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_dev_data *data = dev->data;
@@ -2343,7 +2343,7 @@  ice_dev_stop(struct rte_eth_dev *dev)
 
 	/* avoid stopping again */
 	if (pf->adapter_stopped)
-		return;
+		return 0;
 
 	/* stop and clear all Rx queues */
 	for (i = 0; i < data->nb_rx_queues; i++)
@@ -2369,6 +2369,8 @@  ice_dev_stop(struct rte_eth_dev *dev)
 	}
 
 	pf->adapter_stopped = true;
+
+	return 0;
 }
 
 static int
@@ -2380,6 +2382,7 @@  ice_dev_close(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct ice_adapter *ad =
 		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -2391,7 +2394,9 @@  ice_dev_close(struct rte_eth_dev *dev)
 	 */
 	ice_pf_disable_irq0(hw);
 
-	ice_dev_stop(dev);
+	ret = ice_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	if (!ad->is_safe_mode)
 		ice_flow_uninit(ad);
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index 7f5066df4b..a3e8f112c8 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -179,7 +179,7 @@  static const struct rte_igc_xstats_name_off rte_igc_stats_strings[] = {
 
 static int eth_igc_configure(struct rte_eth_dev *dev);
 static int eth_igc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
-static void eth_igc_stop(struct rte_eth_dev *dev);
+static int eth_igc_stop(struct rte_eth_dev *dev);
 static int eth_igc_start(struct rte_eth_dev *dev);
 static int eth_igc_set_link_up(struct rte_eth_dev *dev);
 static int eth_igc_set_link_down(struct rte_eth_dev *dev);
@@ -607,7 +607,7 @@  eth_igc_rxtx_control(struct rte_eth_dev *dev, bool enable)
  *  This routine disables all traffic on the adapter by issuing a
  *  global reset on the MAC.
  */
-static void
+static int
 eth_igc_stop(struct rte_eth_dev *dev)
 {
 	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
@@ -668,6 +668,8 @@  eth_igc_stop(struct rte_eth_dev *dev)
 		rte_free(intr_handle->intr_vec);
 		intr_handle->intr_vec = NULL;
 	}
+
+	return 0;
 }
 
 /*
@@ -1173,13 +1175,17 @@  eth_igc_close(struct rte_eth_dev *dev)
 	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
 	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
 	int retry = 0;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	if (!adapter->stopped)
-		eth_igc_stop(dev);
+	if (!adapter->stopped) {
+		ret = eth_igc_stop(dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	igc_flow_flush(dev, NULL);
 	igc_clear_all_filter(dev);
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index ef7d06e526..23e785f6dd 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -24,7 +24,7 @@  static int  ionic_dev_info_get(struct rte_eth_dev *eth_dev,
 static int  ionic_dev_configure(struct rte_eth_dev *dev);
 static int  ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int  ionic_dev_start(struct rte_eth_dev *dev);
-static void ionic_dev_stop(struct rte_eth_dev *dev);
+static int  ionic_dev_stop(struct rte_eth_dev *dev);
 static int  ionic_dev_close(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_up(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_down(struct rte_eth_dev *dev);
@@ -940,7 +940,7 @@  ionic_dev_start(struct rte_eth_dev *eth_dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-static void
+static int
 ionic_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
@@ -951,6 +951,8 @@  ionic_dev_stop(struct rte_eth_dev *eth_dev)
 	err = ionic_lif_stop(lif);
 	if (err)
 		IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+
+	return err;
 }
 
 /*
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index b9fb4d4e46..f15ee0728a 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -193,7 +193,7 @@  ipn3ke_rpst_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 ipn3ke_rpst_dev_stop(struct rte_eth_dev *dev)
 {
 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev);
@@ -206,6 +206,8 @@  ipn3ke_rpst_dev_stop(struct rte_eth_dev *dev)
 		/* Disable the RX path */
 		ipn3ke_xmac_rx_disable(hw, rpst->port_id, 0);
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 0b98e210e7..a07a9be9d4 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -142,13 +142,13 @@  static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
 static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
 static int ixgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
 static int ixgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev);
-static int  ixgbe_dev_configure(struct rte_eth_dev *dev);
-static int  ixgbe_dev_start(struct rte_eth_dev *dev);
-static void ixgbe_dev_stop(struct rte_eth_dev *dev);
-static int  ixgbe_dev_set_link_up(struct rte_eth_dev *dev);
-static int  ixgbe_dev_set_link_down(struct rte_eth_dev *dev);
-static int  ixgbe_dev_close(struct rte_eth_dev *dev);
-static int  ixgbe_dev_reset(struct rte_eth_dev *dev);
+static int ixgbe_dev_configure(struct rte_eth_dev *dev);
+static int ixgbe_dev_start(struct rte_eth_dev *dev);
+static int ixgbe_dev_stop(struct rte_eth_dev *dev);
+static int ixgbe_dev_set_link_up(struct rte_eth_dev *dev);
+static int ixgbe_dev_set_link_down(struct rte_eth_dev *dev);
+static int ixgbe_dev_close(struct rte_eth_dev *dev);
+static int ixgbe_dev_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
@@ -250,7 +250,7 @@  static int  ixgbevf_dev_configure(struct rte_eth_dev *dev);
 static int  ixgbevf_dev_start(struct rte_eth_dev *dev);
 static int ixgbevf_dev_link_update(struct rte_eth_dev *dev,
 				   int wait_to_complete);
-static void ixgbevf_dev_stop(struct rte_eth_dev *dev);
+static int ixgbevf_dev_stop(struct rte_eth_dev *dev);
 static int ixgbevf_dev_close(struct rte_eth_dev *dev);
 static int  ixgbevf_dev_reset(struct rte_eth_dev *dev);
 static void ixgbevf_intr_disable(struct rte_eth_dev *dev);
@@ -2845,7 +2845,7 @@  ixgbe_dev_start(struct rte_eth_dev *dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-static void
+static int
 ixgbe_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
@@ -2861,7 +2861,7 @@  ixgbe_dev_stop(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);
 
 	if (hw->adapter_stopped)
-		return;
+		return 0;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -2917,6 +2917,8 @@  ixgbe_dev_stop(struct rte_eth_dev *dev)
 	adapter->rss_reta_updated = 0;
 
 	hw->adapter_stopped = true;
+
+	return 0;
 }
 
 /*
@@ -3000,7 +3002,9 @@  ixgbe_dev_close(struct rte_eth_dev *dev)
 
 	ixgbe_pf_reset_hw(hw);
 
-	ixgbe_dev_stop(dev);
+	ret = ixgbe_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	ixgbe_dev_free_queues(dev);
 
@@ -5401,7 +5405,7 @@  ixgbevf_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 ixgbevf_dev_stop(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5410,7 +5414,7 @@  ixgbevf_dev_stop(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
 	if (hw->adapter_stopped)
-		return;
+		return 0;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -5440,6 +5444,8 @@  ixgbevf_dev_stop(struct rte_eth_dev *dev)
 	}
 
 	adapter->rss_reta_updated = 0;
+
+	return 0;
 }
 
 static int
@@ -5448,6 +5454,7 @@  ixgbevf_dev_close(struct rte_eth_dev *dev)
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
@@ -5455,7 +5462,9 @@  ixgbevf_dev_close(struct rte_eth_dev *dev)
 
 	ixgbe_reset_hw(hw);
 
-	ixgbevf_dev_stop(dev);
+	ret = ixgbevf_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	ixgbe_dev_free_queues(dev);
 
diff --git a/drivers/net/ixgbe/ixgbe_vf_representor.c b/drivers/net/ixgbe/ixgbe_vf_representor.c
index edb5d43846..8185f0d3bb 100644
--- a/drivers/net/ixgbe/ixgbe_vf_representor.c
+++ b/drivers/net/ixgbe/ixgbe_vf_representor.c
@@ -113,8 +113,9 @@  static int ixgbe_vf_representor_dev_start(__rte_unused struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void ixgbe_vf_representor_dev_stop(__rte_unused struct rte_eth_dev *dev)
+static int ixgbe_vf_representor_dev_stop(__rte_unused struct rte_eth_dev *dev)
 {
+	return 0;
 }
 
 static int
diff --git a/drivers/net/kni/rte_eth_kni.c b/drivers/net/kni/rte_eth_kni.c
index be747adf86..9ff763df11 100644
--- a/drivers/net/kni/rte_eth_kni.c
+++ b/drivers/net/kni/rte_eth_kni.c
@@ -177,7 +177,7 @@  eth_kni_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 eth_kni_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
@@ -196,6 +196,8 @@  eth_kni_dev_stop(struct rte_eth_dev *dev)
 	}
 
 	dev->data->dev_link.link_status = 0;
+
+	return 0;
 }
 
 static int
@@ -207,7 +209,9 @@  eth_kni_close(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	eth_kni_dev_stop(eth_dev);
+	ret = eth_kni_dev_stop(eth_dev);
+	if (ret != 0)
+		return ret;
 
 	/* mac_addrs must not be freed alone because part of dev_private */
 	eth_dev->data->mac_addrs = NULL;
@@ -485,6 +489,7 @@  eth_kni_remove(struct rte_vdev_device *vdev)
 {
 	struct rte_eth_dev *eth_dev;
 	const char *name;
+	int ret;
 
 	name = rte_vdev_device_name(vdev);
 	PMD_LOG(INFO, "Un-Initializing eth_kni for %s", name);
@@ -493,7 +498,9 @@  eth_kni_remove(struct rte_vdev_device *vdev)
 	eth_dev = rte_eth_dev_allocated(name);
 	if (eth_dev != NULL) {
 		if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-			eth_kni_dev_stop(eth_dev);
+			ret = eth_kni_dev_stop(eth_dev);
+			if (ret != 0)
+				return ret;
 			return rte_eth_dev_release_port(eth_dev);
 		}
 		eth_kni_close(eth_dev);
diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index 1a41f27198..ffdf72486d 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -1465,7 +1465,7 @@  lio_dev_start(struct rte_eth_dev *eth_dev)
 }
 
 /* Stop device and disable input/output functions */
-static void
+static int
 lio_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1483,6 +1483,8 @@  lio_dev_stop(struct rte_eth_dev *eth_dev)
 
 	/* Clear recorded link status */
 	lio_dev->linfo.link.link_status64 = 0;
+
+	return 0;
 }
 
 static int
@@ -1554,14 +1556,18 @@  static int
 lio_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
+	int ret;
 
 	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)
-		lio_dev_stop(eth_dev);
+	if (lio_dev->intf_open) {
+		ret = lio_dev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	/* Reset ioq regs */
 	lio_dev->fn_list.setup_device_regs(lio_dev);
@@ -1703,6 +1709,7 @@  static int
 lio_reconf_queues(struct rte_eth_dev *eth_dev, int num_txq, int num_rxq)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
+	int ret;
 
 	if (lio_dev->nb_rx_queues != num_rxq ||
 	    lio_dev->nb_tx_queues != num_txq) {
@@ -1712,8 +1719,11 @@  lio_reconf_queues(struct rte_eth_dev *eth_dev, int num_txq, int num_rxq)
 		lio_dev->nb_tx_queues = num_txq;
 	}
 
-	if (lio_dev->intf_open)
-		lio_dev_stop(eth_dev);
+	if (lio_dev->intf_open) {
+		ret = lio_dev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	/* Reset ioq registers */
 	if (lio_dev->fn_list.setup_device_regs(lio_dev)) {
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index cfcfb8a8fc..0857f5e1e3 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -81,7 +81,7 @@  const char *pmd_mlx4_init_params[] = {
 	NULL,
 };
 
-static void mlx4_dev_stop(struct rte_eth_dev *dev);
+static int mlx4_dev_stop(struct rte_eth_dev *dev);
 
 /**
  * Initialize shared data between primary and secondary process.
@@ -343,13 +343,13 @@  mlx4_dev_start(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void
+static int
 mlx4_dev_stop(struct rte_eth_dev *dev)
 {
 	struct mlx4_priv *priv = dev->data->dev_private;
 
 	if (!priv->started)
-		return;
+		return 0;
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
 	dev->tx_pkt_burst = mlx4_tx_burst_removed;
@@ -360,6 +360,8 @@  mlx4_dev_stop(struct rte_eth_dev *dev)
 	mlx4_flow_sync(priv, NULL);
 	mlx4_rxq_intr_disable(priv);
 	mlx4_rss_deinit(priv);
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 87d3c15f07..eb08de7ff3 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1024,7 +1024,7 @@  void *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex);
 /* mlx5_trigger.c */
 
 int mlx5_dev_start(struct rte_eth_dev *dev);
-void mlx5_dev_stop(struct rte_eth_dev *dev);
+int mlx5_dev_stop(struct rte_eth_dev *dev);
 int mlx5_traffic_enable(struct rte_eth_dev *dev);
 void mlx5_traffic_disable(struct rte_eth_dev *dev);
 int mlx5_traffic_restart(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index e72e5fbde2..7735f022a3 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -409,7 +409,7 @@  mlx5_dev_start(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-void
+int
 mlx5_dev_stop(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
@@ -434,6 +434,8 @@  mlx5_dev_stop(struct rte_eth_dev *dev)
 	mlx5_txq_stop(dev);
 	mlx5_rxq_stop(dev);
 	mlx5_txpp_stop(dev);
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/mvneta/mvneta_ethdev.c b/drivers/net/mvneta/mvneta_ethdev.c
index 607771149a..3e4ff6f01c 100644
--- a/drivers/net/mvneta/mvneta_ethdev.c
+++ b/drivers/net/mvneta/mvneta_ethdev.c
@@ -408,19 +408,21 @@  mvneta_dev_start(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void
+static int
 mvneta_dev_stop(struct rte_eth_dev *dev)
 {
 	struct mvneta_priv *priv = dev->data->dev_private;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	mvneta_dev_set_link_down(dev);
 	mvneta_flush_queues(dev);
 	neta_ppio_deinit(priv->ppio);
 
 	priv->ppio = NULL;
+
+	return 0;
 }
 
 /**
@@ -433,13 +435,16 @@  static int
 mvneta_dev_close(struct rte_eth_dev *dev)
 {
 	struct mvneta_priv *priv = dev->data->dev_private;
-	int i;
+	int i, ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	if (priv->ppio)
-		mvneta_dev_stop(dev);
+	if (priv->ppio) {
+		ret = mvneta_dev_stop(dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		mvneta_rx_queue_release(dev->data->rx_queues[i]);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index a230a96840..d7973afe27 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -843,10 +843,10 @@  mrvl_flush_bpool(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void
+static int
 mrvl_dev_stop(struct rte_eth_dev *dev)
 {
-	mrvl_dev_set_link_down(dev);
+	return mrvl_dev_set_link_down(dev);
 }
 
 /**
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index 5ae2d469c8..6f2f0108f5 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -827,7 +827,7 @@  hn_dev_start(struct rte_eth_dev *dev)
 	return error;
 }
 
-static void
+static int
 hn_dev_stop(struct rte_eth_dev *dev)
 {
 	struct hn_data *hv = dev->data->dev_private;
@@ -835,7 +835,7 @@  hn_dev_stop(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	hn_rndis_set_rxfilter(hv, 0);
-	hn_vf_stop(dev);
+	return hn_vf_stop(dev);
 }
 
 static int
@@ -1046,7 +1046,9 @@  eth_hn_dev_uninit(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	hn_dev_stop(eth_dev);
+	ret = hn_dev_stop(eth_dev);
+	if (ret != 0)
+		return ret;
 	hn_dev_close(eth_dev);
 
 	eth_dev->dev_ops = NULL;
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index 4b63f87607..9f8b40c912 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -216,7 +216,7 @@  int	hn_vf_configure(struct rte_eth_dev *dev,
 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);
+int	hn_vf_stop(struct rte_eth_dev *dev);
 void	hn_vf_close(struct rte_eth_dev *dev);
 
 int	hn_vf_allmulticast_enable(struct rte_eth_dev *dev);
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index f5f15c0462..ce896a00bc 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -273,16 +273,23 @@  int hn_vf_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-void hn_vf_stop(struct rte_eth_dev *dev)
+int hn_vf_stop(struct rte_eth_dev *dev)
 {
 	struct hn_data *hv = dev->data->dev_private;
 	struct rte_eth_dev *vf_dev;
+	int ret = 0;
 
 	rte_rwlock_read_lock(&hv->vf_lock);
 	vf_dev = hn_get_vf_dev(hv);
-	if (vf_dev)
-		rte_eth_dev_stop(vf_dev->data->port_id);
+	if (vf_dev) {
+		ret = rte_eth_dev_stop(vf_dev->data->port_id);
+		if (ret != 0)
+			PMD_DRV_LOG(ERR, "Failed to stop device on port %u",
+				    vf_dev->data->port_id);
+	}
 	rte_rwlock_read_unlock(&hv->vf_lock);
+
+	return ret;
 }
 
 /* If VF is present, then cascade configuration down */
diff --git a/drivers/net/nfb/nfb_ethdev.c b/drivers/net/nfb/nfb_ethdev.c
index a9a8bc878d..13f31de2c3 100644
--- a/drivers/net/nfb/nfb_ethdev.c
+++ b/drivers/net/nfb/nfb_ethdev.c
@@ -151,7 +151,7 @@  nfb_eth_dev_start(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void
+static int
 nfb_eth_dev_stop(struct rte_eth_dev *dev)
 {
 	uint16_t i;
@@ -163,6 +163,8 @@  nfb_eth_dev_stop(struct rte_eth_dev *dev)
 
 	for (i = 0; i < nb_rx; i++)
 		nfb_eth_rx_queue_stop(dev, i);
+
+	return 0;
 }
 
 /**
@@ -216,11 +218,14 @@  nfb_eth_dev_close(struct rte_eth_dev *dev)
 	uint16_t i;
 	uint16_t nb_rx = dev->data->nb_rx_queues;
 	uint16_t nb_tx = dev->data->nb_tx_queues;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	nfb_eth_dev_stop(dev);
+	ret = nfb_eth_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	nfb_nc_rxmac_deinit(internals->rxmac, internals->max_rxmac);
 	nfb_nc_txmac_deinit(internals->txmac, internals->max_txmac);
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index c1da66e3d6..38203777a3 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -80,7 +80,7 @@  static int nfp_net_start(struct rte_eth_dev *dev);
 static int nfp_net_stats_get(struct rte_eth_dev *dev,
 			      struct rte_eth_stats *stats);
 static int nfp_net_stats_reset(struct rte_eth_dev *dev);
-static void nfp_net_stop(struct rte_eth_dev *dev);
+static int nfp_net_stop(struct rte_eth_dev *dev);
 static uint16_t nfp_net_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 				  uint16_t nb_pkts);
 
@@ -788,7 +788,7 @@  nfp_net_start(struct rte_eth_dev *dev)
 }
 
 /* Stop device: disable rx and tx functions to allow for reconfiguring. */
-static void
+static int
 nfp_net_stop(struct rte_eth_dev *dev)
 {
 	int i;
@@ -819,6 +819,8 @@  nfp_net_stop(struct rte_eth_dev *dev)
 			nfp_eth_set_configured(dev->process_private,
 					       hw->pf_port_idx, 0);
 	}
+
+	return 0;
 }
 
 /* Set the link up. */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 7c3c76a897..9ed88f110f 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -193,13 +193,15 @@  eth_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	if (dev == NULL)
-		return;
+		return 0;
 
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index aa9ef3bb70..3f08dfca57 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -676,7 +676,7 @@  octeontx_dev_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static void
+static int
 octeontx_dev_stop(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
@@ -690,14 +690,14 @@  octeontx_dev_stop(struct rte_eth_dev *dev)
 	if (ret < 0) {
 		octeontx_log_err("failed to req stop port %d res=%d",
 					nic->port_id, ret);
-		return;
+		return ret;
 	}
 
 	ret = octeontx_pki_port_stop(nic->port_id);
 	if (ret < 0) {
 		octeontx_log_err("failed to stop pki port %d res=%d",
 					nic->port_id, ret);
-		return;
+		return ret;
 	}
 
 	ret = octeontx_pko_channel_stop(nic->base_ochan);
@@ -705,8 +705,10 @@  octeontx_dev_stop(struct rte_eth_dev *dev)
 		octeontx_log_err("failed to stop channel %d VF%d %d %d",
 			     nic->base_ochan, nic->port_id, nic->num_tx_queues,
 			     ret);
-		return;
+		return ret;
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c
index b69b92bf58..e52e1952ba 100644
--- a/drivers/net/octeontx2/otx2_ethdev.c
+++ b/drivers/net/octeontx2/otx2_ethdev.c
@@ -2139,7 +2139,7 @@  otx2_nix_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
 	return rc;
 }
 
-static void
+static int
 otx2_nix_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
@@ -2169,6 +2169,8 @@  otx2_nix_dev_stop(struct rte_eth_dev *eth_dev)
 	/* Stop tx queues  */
 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
 		otx2_nix_tx_queue_stop(eth_dev, i);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 49764c0ee6..595474558b 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -607,7 +607,7 @@  eth_dev_start(struct rte_eth_dev *dev)
  * Is the only place for us to close all the tx streams dumpers.
  * If not called the dumpers will be flushed within each tx burst.
  */
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	unsigned int i;
@@ -649,6 +649,8 @@  eth_dev_stop(struct rte_eth_dev *dev)
 		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
 
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c
index f0de1c8a2e..43c9fb84ec 100644
--- a/drivers/net/pfe/pfe_ethdev.c
+++ b/drivers/net/pfe/pfe_ethdev.c
@@ -373,7 +373,7 @@  pfe_eth_close_cdev(struct pfe_eth_priv_s *priv)
 	}
 }
 
-static void
+static int
 pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/)
 {
 	struct pfe_eth_priv_s *priv = dev->data->dev_private;
@@ -383,11 +383,14 @@  pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/)
 
 	dev->rx_pkt_burst = &pfe_dummy_recv_pkts;
 	dev->tx_pkt_burst = &pfe_dummy_xmit_pkts;
+
+	return 0;
 }
 
 static int
 pfe_eth_close(struct rte_eth_dev *dev)
 {
+	int ret;
 	PMD_INIT_FUNC_TRACE();
 
 	if (!dev)
@@ -399,7 +402,9 @@  pfe_eth_close(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	pfe_eth_stop(dev);
+	ret = pfe_eth_stop(dev);
+	if (ret != 0)
+		return ret;
 	/* Close the device file for link status */
 	pfe_eth_close_cdev(dev->data->dev_private);
 
@@ -667,8 +672,7 @@  pfe_allmulticast_enable(struct rte_eth_dev *dev)
 static int
 pfe_link_down(struct rte_eth_dev *dev)
 {
-	pfe_eth_stop(dev);
-	return 0;
+	return pfe_eth_stop(dev);
 }
 
 static int
@@ -843,7 +847,9 @@  pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)
 
 	eth_dev->data->mtu = 1500;
 	eth_dev->dev_ops = &ops;
-	pfe_eth_stop(eth_dev);
+	err = pfe_eth_stop(eth_dev);
+	if (err != 0)
+		goto err0;
 	pfe_gemac_init(priv);
 
 	eth_dev->data->nb_rx_queues = 1;
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 548497f3ae..ff2a5beea6 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1163,7 +1163,7 @@  static int qede_dev_start(struct rte_eth_dev *eth_dev)
 	return -1; /* common error code is < 0 */
 }
 
-static void qede_dev_stop(struct rte_eth_dev *eth_dev)
+static int qede_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
@@ -1183,7 +1183,7 @@  static void qede_dev_stop(struct rte_eth_dev *eth_dev)
 
 	/* Disable vport */
 	if (qede_activate_vport(eth_dev, false))
-		return;
+		return 0;
 
 	if (qdev->enable_lro)
 		qede_enable_tpa(eth_dev, false);
@@ -1195,6 +1195,8 @@  static void qede_dev_stop(struct rte_eth_dev *eth_dev)
 	ecore_hw_stop_fastpath(edev); /* TBD - loop */
 
 	DP_INFO(edev, "Device is stopped\n");
+
+	return 0;
 }
 
 static const char * const valid_args[] = {
@@ -1549,6 +1551,7 @@  static int qede_dev_close(struct rte_eth_dev *eth_dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	int ret;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -1561,8 +1564,11 @@  static int qede_dev_close(struct rte_eth_dev *eth_dev)
 	 * by the app without reconfiguration. However, in dev_close() we
 	 * can release all the resources and device can be brought up newly
 	 */
-	if (eth_dev->data->dev_started)
-		qede_dev_stop(eth_dev);
+	if (eth_dev->data->dev_started) {
+		ret = qede_dev_stop(eth_dev);
+		if (ret != 0)
+			return ret;
+	}
 
 	if (qdev->vport_started)
 		qede_stop_vport(edev);
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 22c0802688..8f7060340a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -106,10 +106,11 @@  eth_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	return 0;
 }
 
 static int
@@ -235,11 +236,14 @@  eth_dev_close(struct rte_eth_dev *dev)
 	struct pmd_internals *internals = NULL;
 	struct ring_queue *r = NULL;
 	uint16_t i;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	eth_dev_stop(dev);
+	ret = eth_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	internals = dev->data->dev_private;
 	if (internals->action == DEV_CREATE) {
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 165776b652..fed9fc370c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -276,7 +276,7 @@  sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	return ret;
 }
 
-static void
+static int
 sfc_dev_stop(struct rte_eth_dev *dev)
 {
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
@@ -288,6 +288,8 @@  sfc_dev_stop(struct rte_eth_dev *dev)
 	sfc_adapter_unlock(sa);
 
 	sfc_log_init(sa, "done");
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index e942df78b6..3387ab485f 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -178,7 +178,7 @@  pmd_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void
+static int
 pmd_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *p = dev->data->dev_private;
@@ -199,6 +199,8 @@  pmd_dev_stop(struct rte_eth_dev *dev)
 
 	tm_hierarchy_free(p);
 	softnic_mtr_free(p);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 0eecec1e8c..70fa072749 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1013,18 +1013,27 @@  eth_dev_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	uint16_t i;
 	uint16_t nb_rx = dev->data->nb_rx_queues;
 	uint16_t nb_tx = dev->data->nb_tx_queues;
+	int ret;
 
-	for (i = 0; i < nb_tx; i++)
-		eth_tx_queue_stop(dev, i);
+	for (i = 0; i < nb_tx; i++) {
+		ret = eth_tx_queue_stop(dev, i);
+		if (ret != 0)
+			return ret;
+	}
 
-	for (i = 0; i < nb_rx; i++)
-		eth_rx_queue_stop(dev, i);
+	for (i = 0; i < nb_rx; i++) {
+		ret = eth_rx_queue_stop(dev, i);
+		if (ret != 0)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int
@@ -1162,11 +1171,14 @@  eth_dev_close(struct rte_eth_dev *dev)
 	uint16_t i;
 	uint16_t nb_rx = dev->data->nb_rx_queues;
 	uint16_t nb_tx = dev->data->nb_tx_queues;
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	eth_dev_stop(dev);
+	ret = eth_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	free(internals->sze_dev_path);
 
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index e592a469b3..7047a42ce8 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -900,7 +900,7 @@  tap_dev_start(struct rte_eth_dev *dev)
 
 /* This function gets called when the current port gets stopped.
  */
-static void
+static int
 tap_dev_stop(struct rte_eth_dev *dev)
 {
 	int i;
@@ -912,6 +912,8 @@  tap_dev_stop(struct rte_eth_dev *dev)
 
 	tap_intr_handle_set(dev, 0);
 	tap_link_set_down(dev);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index cc6eb4ba24..7ff4cdcb86 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -44,7 +44,7 @@ 
 #include "nicvf_svf.h"
 #include "nicvf_logs.h"
 
-static void nicvf_dev_stop(struct rte_eth_dev *dev);
+static int nicvf_dev_stop(struct rte_eth_dev *dev);
 static void nicvf_dev_stop_cleanup(struct rte_eth_dev *dev, bool cleanup);
 static void nicvf_vf_stop(struct rte_eth_dev *dev, struct nicvf *nic,
 			  bool cleanup);
@@ -1789,12 +1789,14 @@  nicvf_dev_stop_cleanup(struct rte_eth_dev *dev, bool cleanup)
 		PMD_INIT_LOG(ERR, "Failed to reclaim CPI config %d", ret);
 }
 
-static void
+static int
 nicvf_dev_stop(struct rte_eth_dev *dev)
 {
 	PMD_INIT_FUNC_TRACE();
 
 	nicvf_dev_stop_cleanup(dev, false);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 66efecb320..f303caa5bf 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -1153,13 +1153,15 @@  eth_dev_start(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-static void
+static int
 eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internal *internal = dev->data->dev_private;
 
 	rte_atomic32_set(&internal->started, 0);
 	update_queuing_status(dev);
+
+	return 0;
 }
 
 static int
@@ -1167,7 +1169,7 @@  eth_dev_close(struct rte_eth_dev *dev)
 {
 	struct pmd_internal *internal;
 	struct internal_list *list;
-	unsigned int i;
+	unsigned int i, ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -1176,7 +1178,9 @@  eth_dev_close(struct rte_eth_dev *dev)
 	if (!internal)
 		return 0;
 
-	eth_dev_stop(dev);
+	ret = eth_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 
 	list = find_internal_resource(internal->iface_name);
 	if (list) {
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0236c756dc..64291a3adb 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -40,7 +40,7 @@ 
 static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
 static int  virtio_dev_start(struct rte_eth_dev *dev);
-static void virtio_dev_stop(struct rte_eth_dev *dev);
+static int  virtio_dev_stop(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
@@ -1993,12 +1993,15 @@  eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 static int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
+	int ret;
 	PMD_INIT_FUNC_TRACE();
 
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
 		return 0;
 
-	virtio_dev_stop(eth_dev);
+	ret = virtio_dev_stop(eth_dev);
+	if (ret != 0)
+		return ret;
 	virtio_dev_close(eth_dev);
 
 	eth_dev->dev_ops = NULL;
@@ -2515,7 +2518,7 @@  static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 /*
  * Stop device: disable interrupt and mark link down
  */
-static void
+static int
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -2544,6 +2547,8 @@  virtio_dev_stop(struct rte_eth_dev *dev)
 	rte_eth_linkstatus_set(dev, &link);
 out_unlock:
 	rte_spinlock_unlock(&hw->state_lock);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index fa950e1ba0..ad05fe08b9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -63,7 +63,7 @@  static int eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev);
 static int vmxnet3_dev_configure(struct rte_eth_dev *dev);
 static int vmxnet3_dev_start(struct rte_eth_dev *dev);
-static void vmxnet3_dev_stop(struct rte_eth_dev *dev);
+static int vmxnet3_dev_stop(struct rte_eth_dev *dev);
 static int vmxnet3_dev_close(struct rte_eth_dev *dev);
 static void vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set);
 static int vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev);
@@ -814,7 +814,7 @@  vmxnet3_dev_start(struct rte_eth_dev *dev)
 /*
  * Stop device: disable rx and tx functions to allow for reconfiguring.
  */
-static void
+static int
 vmxnet3_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
@@ -824,7 +824,7 @@  vmxnet3_dev_stop(struct rte_eth_dev *dev)
 
 	if (hw->adapter_stopped == 1) {
 		PMD_INIT_LOG(DEBUG, "Device already stopped.");
-		return;
+		return 0;
 	}
 
 	/* disable interrupts */
@@ -858,6 +858,8 @@  vmxnet3_dev_stop(struct rte_eth_dev *dev)
 	rte_eth_linkstatus_set(dev, &link);
 
 	hw->adapter_stopped = 1;
+
+	return 0;
 }
 
 static void
@@ -888,11 +890,14 @@  vmxnet3_free_queues(struct rte_eth_dev *dev)
 static int
 vmxnet3_dev_close(struct rte_eth_dev *dev)
 {
+	int ret;
 	PMD_INIT_FUNC_TRACE();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	vmxnet3_dev_stop(dev);
+	ret = vmxnet3_dev_stop(dev);
+	if (ret != 0)
+		return ret;
 	vmxnet3_free_queues(dev);
 
 	return 0;
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 2226e429ba..61a20653f4 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1719,6 +1719,7 @@  int
 rte_eth_dev_stop(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
@@ -1733,10 +1734,10 @@  rte_eth_dev_stop(uint16_t port_id)
 	}
 
 	dev->data->dev_started = 0;
-	(*dev->dev_ops->dev_stop)(dev);
-	rte_ethdev_trace_stop(port_id);
+	ret = (*dev->dev_ops->dev_stop)(dev);
+	rte_ethdev_trace_stop(port_id, ret);
 
-	return 0;
+	return ret;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 35cc4fb186..1c1c10d583 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -33,7 +33,7 @@  typedef int  (*eth_dev_configure_t)(struct rte_eth_dev *dev);
 typedef int  (*eth_dev_start_t)(struct rte_eth_dev *dev);
 /**< @internal Function used to start a configured Ethernet device. */
 
-typedef void (*eth_dev_stop_t)(struct rte_eth_dev *dev);
+typedef int (*eth_dev_stop_t)(struct rte_eth_dev *dev);
 /**< @internal Function used to stop a configured Ethernet device. */
 
 typedef int  (*eth_dev_set_link_up_t)(struct rte_eth_dev *dev);
diff --git a/lib/librte_ethdev/rte_ethdev_trace.h b/lib/librte_ethdev/rte_ethdev_trace.h
index 16f5bf24b9..0036bda746 100644
--- a/lib/librte_ethdev/rte_ethdev_trace.h
+++ b/lib/librte_ethdev/rte_ethdev_trace.h
@@ -77,8 +77,9 @@  RTE_TRACE_POINT(
 
 RTE_TRACE_POINT(
 	rte_ethdev_trace_stop,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id),
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, int ret),
 	rte_trace_point_emit_u16(port_id);
+	rte_trace_point_emit_int(ret);
 )
 
 RTE_TRACE_POINT(