RE: [PATCH 5/5] net/iavf: improve VF reset detection on fast ARQ flip

"Loftus, Ciara" <[email protected]>
Newsgroups org.dpdk.dev
Message-ID <IA4PR11MB9278C66FA76806F9DCC652408ED12@IA4PR11MB9278.namprd11.prod.outlook.com>
> Subject: [PATCH 5/5] net/iavf: improve VF reset detection on fast ARQ flip
> 
> During PF-initiated reset or a remote/ToR switch link-flap,
> the PF toggles the admin receive queue enable bit (ARQLEN1)
> so quickly around a VF reset that the VF's sampling window
> misses it, leaving the PF and the VF states out of sync
> and the data path stalled.
> 
> Complement the ARQLEN1 check with VFGEN_RSTAT
> (VIRTCHNL_VFR_INPROGRESS) and shorten the poll interval to
> 5 ms (with a proportionally larger count, keeping the ~10 s
> budget), matching the Linux kernel iavf driver.
> When the VFR is still not observed, proceed with recovery
> instead of bailing out so the PF and  the VF states converge.
> 
> Fixes: ada64daa1a5b ("net/iavf: fix VF reset for flow director rule")
> Fixes: 80fb3c920458 ("net/iavf: fix crash on VF start")
> Cc: [email protected]
> 
> Signed-off-by: Anurag Mandal <[email protected]>
> ---
>  drivers/net/intel/iavf/iavf.h        |  1 +
>  drivers/net/intel/iavf/iavf_ethdev.c | 41 +++++++++++++++++++++-------
>  2 files changed, 32 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
> index 037bc8436f..5e49e81447 100644
> --- a/drivers/net/intel/iavf/iavf.h
> +++ b/drivers/net/intel/iavf/iavf.h
> @@ -21,6 +21,7 @@
>  #define IAVF_AQ_BUF_SZ            4096
>  #define IAVF_RESET_WAIT_CNT       2000
>  #define IAVF_RESET_DETECTED_CNT   500
> +#define IAVF_RESET_POLL_SCALE     4  /* Poll-interval scale for reset detection
> */
>  #define IAVF_BUF_SIZE_MIN         1024
>  #define IAVF_FRAME_SIZE_MAX       9728
>  #define IAVF_QUEUE_BASE_ADDR_UNIT 128
> diff --git a/drivers/net/intel/iavf/iavf_ethdev.c
> b/drivers/net/intel/iavf/iavf_ethdev.c
> index f6ce339b0c..21bac51467 100644
> --- a/drivers/net/intel/iavf/iavf_ethdev.c
> +++ b/drivers/net/intel/iavf/iavf_ethdev.c
> @@ -3235,7 +3235,9 @@ iavf_dev_close(struct rte_eth_dev *dev)
>  	/* remove RSS configuration */
>  	iavf_hash_uninit(adapter);
> 
> -	iavf_flow_flush(dev, NULL);
> +	/* Skip the virtchnl-emitting teardown on a PF-initiated reset */
> +	if (!vf->pf_reset_in_progress)
> +		iavf_flow_flush(dev, NULL);

This seems like a valid change but unrelated to the rest of the commit.
Consider splitting it out.

>  	iavf_flow_uninit(adapter);
> 
>  	/*
> @@ -3358,8 +3360,26 @@ iavf_dev_reset(struct rte_eth_dev *dev)
>  static inline bool
>  iavf_is_reset(struct iavf_hw *hw)
>  {
> -	return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
> -		IAVF_VF_ARQLEN1_ARQENABLE_MASK);
> +	uint32_t rstat;
> +
> +	/* ARQ has been disabled by the PF as part of the VFR. */
> +	if (!(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
> +		IAVF_VF_ARQLEN1_ARQENABLE_MASK))
> +		return true;
> +
> +	/*
> +	 * VFGEN_RSTAT reports VIRTCHNL_VFR_INPROGRESS.
> +	 * At times, the PF flips ARQENABLE so quickly
> +	 * around a VFR that the ARQLEN1 sample window
> +	 * misses it. Using VFGEN_RSTAT, as a
> +	 * complementary indicator, prevents from
> +	 * missing a reset that really did happen.
> +	 */
> +	rstat = (IAVF_READ_REG(hw, IAVF_VFGEN_RSTAT) &
> +		 IAVF_VFGEN_RSTAT_VFR_STATE_MASK) >>
> +		IAVF_VFGEN_RSTAT_VFR_STATE_SHIFT;
> +
> +	return rstat == VIRTCHNL_VFR_INPROGRESS;
>  }
> 
>  static bool
> @@ -3368,11 +3388,14 @@ 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++) {
> +	/*
> +	 * Poll until the reset actually happen.
> +	 * Poll every 5 ms to catch the fast ARQ flips.
> +	 */
> +	for (i = 0; i < IAVF_RESET_DETECTED_CNT * IAVF_RESET_POLL_SCALE;
> i++) {
>  		if (iavf_is_reset(hw))
>  			return true;
> -		rte_delay_ms(20);
> +		rte_delay_us(5000);
>  	}
> 
>  	return false;
> @@ -3423,10 +3446,8 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev,
> bool vf_initiated_reset)
>  		if (!dev->data->dev_started)
>  			return;
> 
> -		if (!iavf_is_reset_detected(adapter)) {
> -			PMD_DRV_LOG(DEBUG, "reset not start");
> -			return;
> -		}
> +		if (!iavf_is_reset_detected(adapter))
> +			PMD_DRV_LOG(WARNING, "VFR not observed;
> recovering anyway");
>  	}
> 
>  	vf->in_reset_recovery = true;
> --
> 2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.