When the vf starts to request multiple queues, the pf sends a reset command to the vf. During the reset process, adminq sends an abnormal message to pf for an unknown reason, and the resource request fails resulting in a coredump.
This patch fixes the issue by checking the reset state before resetting. v2: fix windows compilation errors Signed-off-by: Shiyang He <shiyangx...@intel.com> --- drivers/net/iavf/iavf.h | 3 ++- drivers/net/iavf/iavf_ethdev.c | 48 +++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h index 10868f2c30..cdf60bd833 100644 --- a/drivers/net/iavf/iavf.h +++ b/drivers/net/iavf/iavf.h @@ -19,6 +19,7 @@ #define IAVF_AQ_LEN 32 #define IAVF_AQ_BUF_SZ 4096 #define IAVF_RESET_WAIT_CNT 500 +#define IAVF_RESET_DETECTED_CNT 500 #define IAVF_BUF_SIZE_MIN 1024 #define IAVF_FRAME_SIZE_MAX 9728 #define IAVF_QUEUE_BASE_ADDR_UNIT 128 @@ -511,5 +512,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter); void iavf_dev_watchdog_enable(struct iavf_adapter *adapter); void iavf_dev_watchdog_disable(struct iavf_adapter *adapter); -int iavf_handle_hw_reset(struct rte_eth_dev *dev); +void iavf_handle_hw_reset(struct rte_eth_dev *dev); #endif /* _IAVF_ETHDEV_H_ */ diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index d1edb0dd5c..06b18f2758 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -1086,9 +1086,6 @@ iavf_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); - if (vf->vf_reset) - return 0; - if (adapter->closed) return -1; @@ -2949,7 +2946,6 @@ iavf_dev_reset(struct rte_eth_dev *dev) { int ret; struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); /* * Check whether the VF reset has been done and inform application, @@ -2961,7 +2957,6 @@ iavf_dev_reset(struct rte_eth_dev *dev) PMD_DRV_LOG(ERR, "Wait too long for reset done!\n"); return ret; } - vf->vf_reset = false; PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n"); ret = iavf_dev_uninit(dev); @@ -2971,15 +2966,47 @@ iavf_dev_reset(struct rte_eth_dev *dev) return iavf_dev_init(dev); } +static inline bool +iavf_is_reset(struct iavf_hw *hw) +{ + return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) & + IAVF_VF_ARQLEN1_ARQENABLE_MASK); +} + +static bool +iavf_is_reset_detected(struct iavf_adapter *adapter) +{ + struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter); + int i; + + /* poll until we see the reset actually happen */ + for (i = 0; i < IAVF_RESET_DETECTED_CNT; i++) { + if (iavf_is_reset(hw)) + return true; + rte_delay_ms(20); + } + + return false; +} + /* * Handle hardware reset */ -int +void iavf_handle_hw_reset(struct rte_eth_dev *dev) { struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + struct iavf_adapter *adapter = dev->data->dev_private; int ret; + if (!dev->data->dev_started) + return; + + if (!iavf_is_reset_detected(adapter)) { + PMD_DRV_LOG(DEBUG, "reset not start\n"); + return; + } + vf->in_reset_recovery = true; ret = iavf_dev_reset(dev); @@ -2997,15 +3024,16 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev) ret = iavf_dev_start(dev); if (ret) goto error; - dev->data->dev_started = 1; + dev->data->dev_started = 1; vf->in_reset_recovery = false; - return 0; + + return; error: - PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret); vf->in_reset_recovery = false; - return ret; + iavf_uninit_vf(dev); + PMD_DRV_LOG(DEBUG, "failed to reset port %d\n", dev->data->port_id); } static int -- 2.34.1