--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -260,7 +260,7 @@ static void eth_igb_configure_msix_intr(
 static void eth_igbvf_interrupt_handler(struct rte_intr_handle *handle,
 					void *param);
 static void igbvf_mbx_process(struct rte_eth_dev *dev);
-static int igbvf_dev_reset(struct rte_eth_dev *dev);
+static int igbvf_dev_reset(struct rte_eth_dev *dev, int blocking);
 
 /*
  * Define VF Stats MACRO for Non "cleared on read" register
@@ -2598,7 +2598,7 @@ void igbvf_mbx_process(struct rte_eth_de
 }
 
 static int
-igbvf_dev_reset(struct rte_eth_dev *dev)
+igbvf_dev_reset(struct rte_eth_dev *dev, __rte_unused int blocking)
 {
 	struct e1000_hw *hw =
 		 E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -2626,12 +2626,12 @@ igbvf_dev_reset(struct rte_eth_dev *dev)
 		 rte_delay_ms(1000);
 
 		 diag = igbvf_dev_start(dev);
+		 dev->data->dev_started = 1;
 		 if (diag) {
 			  PMD_INIT_LOG(ERR, "Igb VF reset: "
 					 "Failed to start device.");
-			  return diag;
+			  return -EAGAIN;
 		 }
-		 dev->data->dev_started = 1;
 		 eth_igbvf_stats_reset(dev);
 		 if (dev->data->dev_conf.intr_conf.lsc == 0)
 			  diag = eth_igb_link_update(dev, 0);
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -157,7 +157,7 @@ static int i40evf_dev_init(struct rte_et
 static void i40evf_dev_close(struct rte_eth_dev *dev);
 static int i40evf_dev_start(struct rte_eth_dev *dev);
 static int i40evf_dev_configure(struct rte_eth_dev *dev);
-static int i40evf_handle_vf_reset(struct rte_eth_dev *dev);
+static int i40evf_handle_vf_reset(struct rte_eth_dev *dev, int blocking);
 
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
@@ -1498,7 +1498,7 @@ i40e_vf_reset_dev(struct rte_eth_dev *de
 }
 
 static int
-i40evf_handle_vf_reset(struct rte_eth_dev *dev)
+i40evf_handle_vf_reset(struct rte_eth_dev *dev, __rte_unused int blocking)
 {
 	struct i40e_adapter *adapter =
 		 I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
@@ -1518,7 +1518,7 @@ i40evf_emulate_vf_reset(uint8_t port_id)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 
-	i40evf_handle_vf_reset(dev);
+	i40evf_handle_vf_reset(dev, 0);
 }
 
 static int
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -379,7 +379,7 @@ static void ixgbevf_dev_interrupt_handle
 		(r) = (h)->bitmap[idx] >> bit & 1;\
 	}while(0)
 
-static int ixgbevf_dev_reset(struct rte_eth_dev *dev);
+static int ixgbevf_dev_reset(struct rte_eth_dev *dev, int blocking);
 
 /*
  * The set of PCI devices this driver supports
@@ -6227,7 +6227,7 @@ static void ixgbevf_mbx_process(struct r
 }
 
 static int
-ixgbevf_dev_reset(struct rte_eth_dev *dev)
+ixgbevf_dev_reset(struct rte_eth_dev *dev, int blocking)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	int diag = 0;
@@ -6256,7 +6256,12 @@ ixgbevf_dev_reset(struct rte_eth_dev *de
 		 if (diag) {
 			  PMD_INIT_LOG(ERR, "Ixgbe VF reset: "
 					 "Failed to start device.");
-			  continue;
+			if (blocking)
+				continue;
+			else {
+				dev->data->dev_started = 1;
+				return -EAGAIN;
+			}
 		 }
 		 dev->data->dev_started = 1;
 		 ixgbevf_dev_stats_reset(dev);
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3370,7 +3370,7 @@ rte_eth_copy_pci_info(struct rte_eth_dev
 }
 
 int
-rte_eth_dev_reset(uint8_t port_id)
+rte_eth_dev_reset(uint8_t port_id, int blocking)
 {
 	struct rte_eth_dev *dev;
 	int diag;
@@ -3381,7 +3381,7 @@ rte_eth_dev_reset(uint8_t port_id)
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
 
-	diag = (*dev->dev_ops->dev_reset)(dev);
+	diag = (*dev->dev_ops->dev_reset)(dev, blocking);
 
 	return diag;
 }
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1262,7 +1262,7 @@ typedef int (*eth_set_eeprom_t)(struct r
 				struct rte_dev_eeprom_info *info);
 /**< @internal Program eeprom data  */
 
-typedef int  (*eth_dev_reset_t)(struct rte_eth_dev *dev);
+typedef int  (*eth_dev_reset_t)(struct rte_eth_dev *dev, int blocking);
 /**< @internal Function used to reset a configured Ethernet device. */
 
 #ifdef RTE_NIC_BYPASS
@@ -3927,17 +3927,21 @@ rte_eth_dma_zone_reserve(const struct rt
  * queues, restart the port.
  * Before calling this API, APP should stop the rx/tx. When tx is being stopped,
  * APP can drop the packets and release the buffer instead of sending them.
+ * This call will block until the PF is up again, unless blocking is false.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
+ * @param blocking
+ *   Whether or not to block if the PF is not yet UP.
  *
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-ENOTSUP) if hardware doesn't support this function.
+ *   - (-EAGAIN) if PF is not up and blocking was false.
  */
 int
-rte_eth_dev_reset(uint8_t port_id);
+rte_eth_dev_reset(uint8_t port_id, int blocking);
 
 #ifdef __cplusplus
 }
