diff mbox series

[net,v2] ice: Fix ice VF reset during iavf initialization

Message ID 20230418095255.165004-1-kamil.maziarz@intel.com
State Accepted
Delegated to: Anthony Nguyen
Headers show
Series [net,v2] ice: Fix ice VF reset during iavf initialization | expand

Commit Message

Kamil Maziarz April 18, 2023, 9:52 a.m. UTC
From: Dawid Wesierski <dawidx.wesierski@intel.com>

Fix the current implementation that causes ice_trigger_vf_reset()
to start resetting the VF even when the VF is still resetting itself
and initializing adminq. This leads to a series of -53 errors
(failed to init adminq) from the IAVF.

Change the state of the vf_state field to be not active when the IAVF
asks for a reset. To avoid issues caused by the VF being reset too
early, make sure to wait until receiving the message on the message
box to know the exact state of the IAVF driver.

Fixes: c54d209c78b8 ("ice: Wait for VF to be reset/ready before configuration")
Signed-off-by: Dawid Wesierski <dawidx.wesierski@intel.com>
Signed-off-by: Kamil Maziarz <kamil.maziarz@intel.com>
Acked-by: Jacob Keller <Jacob.e.keller@intel.com>
---
v2: changed "reseted" to "reset", changed fixes tag, removed space
---
 drivers/net/ethernet/intel/ice/ice_sriov.c    |  8 ++++----
 drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 19 +++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_vf_lib.h   |  1 +
 drivers/net/ethernet/intel/ice/ice_virtchnl.c |  1 +
 4 files changed, 25 insertions(+), 4 deletions(-)

Comments

Romanowski, Rafal April 24, 2023, 1:25 p.m. UTC | #1
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Kamil Maziarz
> Sent: wtorek, 18 kwietnia 2023 11:53
> To: intel-wired-lan@lists.osuosl.org
> Cc: Wesierski, DawidX <dawidx.wesierski@intel.com>; Maziarz, Kamil
> <kamil.maziarz@intel.com>
> Subject: [Intel-wired-lan] [PATCH net v2] ice: Fix ice VF reset during iavf
> initialization
> 
> From: Dawid Wesierski <dawidx.wesierski@intel.com>
> 
> Fix the current implementation that causes ice_trigger_vf_reset() to start
> resetting the VF even when the VF is still resetting itself and initializing
> adminq. This leads to a series of -53 errors (failed to init adminq) from the
> IAVF.
> 
> Change the state of the vf_state field to be not active when the IAVF asks for
> a reset. To avoid issues caused by the VF being reset too early, make sure to
> wait until receiving the message on the message box to know the exact state
> of the IAVF driver.
> 
> Fixes: c54d209c78b8 ("ice: Wait for VF to be reset/ready before
> configuration")
> Signed-off-by: Dawid Wesierski <dawidx.wesierski@intel.com>
> Signed-off-by: Kamil Maziarz <kamil.maziarz@intel.com>
> Acked-by: Jacob Keller <Jacob.e.keller@intel.com>
> ---
> v2: changed "reseted" to "reset", changed fixes tag, removed space
> ---
>  drivers/net/ethernet/intel/ice/ice_sriov.c    |  8 ++++----
>  drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 19 +++++++++++++++++++
>  drivers/net/ethernet/intel/ice/ice_vf_lib.h   |  1 +
>  drivers/net/ethernet/intel/ice/ice_virtchnl.c |  1 +
>  4 files changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c
> b/drivers/net/ethernet/intel/ice/ice_sriov.c
> index 0cc05e54a781..d4206db7d6d5 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sriov.c
> +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c


Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Petr Oros Aug. 4, 2023, 11:16 a.m. UTC | #2
Kamil Maziarz píše v Út 18. 04. 2023 v 11:52 +0200:
> From: Dawid Wesierski <dawidx.wesierski@intel.com>
> 
> Fix the current implementation that causes ice_trigger_vf_reset()
> to start resetting the VF even when the VF is still resetting itself
> and initializing adminq. This leads to a series of -53 errors
> (failed to init adminq) from the IAVF.
> 
> Change the state of the vf_state field to be not active when the IAVF
> asks for a reset. To avoid issues caused by the VF being reset too
> early, make sure to wait until receiving the message on the message
> box to know the exact state of the IAVF driver.
> 
> Fixes: c54d209c78b8 ("ice: Wait for VF to be reset/ready before
> configuration")
> Signed-off-by: Dawid Wesierski <dawidx.wesierski@intel.com>
> Signed-off-by: Kamil Maziarz <kamil.maziarz@intel.com>
> Acked-by: Jacob Keller <Jacob.e.keller@intel.com>
> ---
> v2: changed "reseted" to "reset", changed fixes tag, removed space
> ---
>  drivers/net/ethernet/intel/ice/ice_sriov.c    |  8 ++++----
>  drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 19
> +++++++++++++++++++
>  drivers/net/ethernet/intel/ice/ice_vf_lib.h   |  1 +
>  drivers/net/ethernet/intel/ice/ice_virtchnl.c |  1 +
>  4 files changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c
> b/drivers/net/ethernet/intel/ice/ice_sriov.c
> index 0cc05e54a781..d4206db7d6d5 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sriov.c
> +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
> @@ -1181,7 +1181,7 @@ int ice_set_vf_spoofchk(struct net_device
> *netdev, int vf_id, bool ena)
>         if (!vf)
>                 return -EINVAL;
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1296,7 +1296,7 @@ int ice_set_vf_mac(struct net_device *netdev,
> int vf_id, u8 *mac)
>                 goto out_put_vf;
>         }
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1350,7 +1350,7 @@ int ice_set_vf_trust(struct net_device *netdev,
> int vf_id, bool trusted)
>                 return -EOPNOTSUPP;
>         }
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1663,7 +1663,7 @@ ice_set_vf_port_vlan(struct net_device *netdev,
> int vf_id, u16 vlan_id, u8 qos,
>         if (!vf)
>                 return -EINVAL;
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> index 0e57bd1b85fd..95878c95e953 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> @@ -185,6 +185,25 @@ int ice_check_vf_ready_for_cfg(struct ice_vf
> *vf)
>         return 0;
>  }
>  
> +/**
> + * ice_check_vf_ready_for_reset - check if VF is ready to be reset
> + * @vf: VF to check if it's ready to be reset
> + *
> + * The purpose of this function is to ensure that the VF is not in
> reset,
> + * disabled, and is both initialized and active, thus enabling us to
> safely
> + * initialize another reset.
> + */
> +int ice_check_vf_ready_for_reset(struct ice_vf *vf)
> +{
> +       int ret;
> +
> +       ret = ice_check_vf_ready_for_cfg(vf);
> +       if (!ret && !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
> +               ret = -EAGAIN;
> +
> +       return ret;
> +}
> +
>  /**
>   * ice_trigger_vf_reset - Reset a VF on HW
>   * @vf: pointer to the VF structure
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> index ef30f05b5d02..3fc6a0a8d955 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> @@ -215,6 +215,7 @@ u16 ice_get_num_vfs(struct ice_pf *pf);
>  struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
>  bool ice_is_vf_disabled(struct ice_vf *vf);
>  int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
> +int ice_check_vf_ready_for_reset(struct ice_vf *vf);
>  void ice_set_vf_state_dis(struct ice_vf *vf);
>  bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);
>  void
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> index e24e3f5017ca..d8c66baf4eb4 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> @@ -3908,6 +3908,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf,
> struct ice_rq_event_info *event)
>                 ice_vc_notify_vf_link_state(vf);
>                 break;
>         case VIRTCHNL_OP_RESET_VF:
> +               clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
>                 ops->reset_vf(vf);
>                 break;
>         case VIRTCHNL_OP_ADD_ETH_ADDR:

Hi Dawid,

How was this patch tested?

Why are we waiting for ICE_VF_STATE_ACTIVE? As I understand
ICE_VF_STATE_INIT is the state where we can start the reset again.

After this patch we are not able to attach VF to VM:

# virsh attach-interface v0 hostdev --managed 0000:41:01.0 --mac
52:54:00:b4:aa:bb
# error: Failed to attach interface
# error: Cannot set interface MAC to 52:54:00:b4:aa:bb for ifname
enp65s0f0np0 vf 0: Resource temporarily unavailable

Regards,
Petr
Petr Oros Aug. 4, 2023, 11:29 a.m. UTC | #3
Kamil Maziarz píše v Čt 01. 01. 1970 v 00:00 +0000:
> From: Dawid Wesierski <dawidx.wesierski@intel.com>
> 
> Fix the current implementation that causes ice_trigger_vf_reset()
> to start resetting the VF even when the VF is still resetting itself
> and initializing adminq. This leads to a series of -53 errors
> (failed to init adminq) from the IAVF.
> 
> Change the state of the vf_state field to be not active when the IAVF
> asks for a reset. To avoid issues caused by the VF being reset too
> early, make sure to wait until receiving the message on the message
> box to know the exact state of the IAVF driver.
> 
> Fixes: c54d209c78b8 ("ice: Wait for VF to be reset/ready before
> configuration")
> Signed-off-by: Dawid Wesierski <dawidx.wesierski@intel.com>
> Signed-off-by: Kamil Maziarz <kamil.maziarz@intel.com>
> Acked-by: Jacob Keller <Jacob.e.keller@intel.com>
> ---
> v2: changed "reseted" to "reset", changed fixes tag, removed space
> ---
>  drivers/net/ethernet/intel/ice/ice_sriov.c    |  8 ++++----
>  drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 19
> +++++++++++++++++++
>  drivers/net/ethernet/intel/ice/ice_vf_lib.h   |  1 +
>  drivers/net/ethernet/intel/ice/ice_virtchnl.c |  1 +
>  4 files changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c
> b/drivers/net/ethernet/intel/ice/ice_sriov.c
> index 0cc05e54a781..d4206db7d6d5 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sriov.c
> +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
> @@ -1181,7 +1181,7 @@ int ice_set_vf_spoofchk(struct net_device
> *netdev, int vf_id, bool ena)
>         if (!vf)
>                 return -EINVAL;
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1296,7 +1296,7 @@ int ice_set_vf_mac(struct net_device *netdev,
> int vf_id, u8 *mac)
>                 goto out_put_vf;
>         }
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1350,7 +1350,7 @@ int ice_set_vf_trust(struct net_device *netdev,
> int vf_id, bool trusted)
>                 return -EOPNOTSUPP;
>         }
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> @@ -1663,7 +1663,7 @@ ice_set_vf_port_vlan(struct net_device *netdev,
> int vf_id, u16 vlan_id, u8 qos,
>         if (!vf)
>                 return -EINVAL;
>  
> -       ret = ice_check_vf_ready_for_cfg(vf);
> +       ret = ice_check_vf_ready_for_reset(vf);
>         if (ret)
>                 goto out_put_vf;
>  
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> index 0e57bd1b85fd..95878c95e953 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> @@ -185,6 +185,25 @@ int ice_check_vf_ready_for_cfg(struct ice_vf
> *vf)
>         return 0;
>  }
>  
> +/**
> + * ice_check_vf_ready_for_reset - check if VF is ready to be reset
> + * @vf: VF to check if it's ready to be reset
> + *
> + * The purpose of this function is to ensure that the VF is not in
> reset,
> + * disabled, and is both initialized and active, thus enabling us to
> safely
> + * initialize another reset.
> + */
> +int ice_check_vf_ready_for_reset(struct ice_vf *vf)
> +{
> +       int ret;
> +
> +       ret = ice_check_vf_ready_for_cfg(vf);
> +       if (!ret && !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
> +               ret = -EAGAIN;
> +
> +       return ret;
> +}
> +
>  /**
>   * ice_trigger_vf_reset - Reset a VF on HW
>   * @vf: pointer to the VF structure
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> index ef30f05b5d02..3fc6a0a8d955 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
> @@ -215,6 +215,7 @@ u16 ice_get_num_vfs(struct ice_pf *pf);
>  struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
>  bool ice_is_vf_disabled(struct ice_vf *vf);
>  int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
> +int ice_check_vf_ready_for_reset(struct ice_vf *vf);
>  void ice_set_vf_state_dis(struct ice_vf *vf);
>  bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);
>  void
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> index e24e3f5017ca..d8c66baf4eb4 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> @@ -3908,6 +3908,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf,
> struct ice_rq_event_info *event)
>                 ice_vc_notify_vf_link_state(vf);
>                 break;
>         case VIRTCHNL_OP_RESET_VF:
> +               clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
>                 ops->reset_vf(vf);
>                 break;
>         case VIRTCHNL_OP_ADD_ETH_ADDR:


Hi,

How was this patch tested?

Why are we waiting for ICE_VF_STATE_ACTIVE? As I understand
ICE_VF_STATE_INIT is the state where we can start the reset again.

After this patch we are not able to attach VF to VM:

# virsh attach-interface v0 hostdev --managed 0000:41:01.0 --mac
52:54:00:b4:aa:bb
# error: Failed to attach interface
# error: Cannot set interface MAC to 52:54:00:b4:aa:bb for ifname
enp65s0f0np0 vf 0: Resource temporarily unavailable

Regards,
Petr
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
index 0cc05e54a781..d4206db7d6d5 100644
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
@@ -1181,7 +1181,7 @@  int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena)
 	if (!vf)
 		return -EINVAL;
 
-	ret = ice_check_vf_ready_for_cfg(vf);
+	ret = ice_check_vf_ready_for_reset(vf);
 	if (ret)
 		goto out_put_vf;
 
@@ -1296,7 +1296,7 @@  int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
 		goto out_put_vf;
 	}
 
-	ret = ice_check_vf_ready_for_cfg(vf);
+	ret = ice_check_vf_ready_for_reset(vf);
 	if (ret)
 		goto out_put_vf;
 
@@ -1350,7 +1350,7 @@  int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
 		return -EOPNOTSUPP;
 	}
 
-	ret = ice_check_vf_ready_for_cfg(vf);
+	ret = ice_check_vf_ready_for_reset(vf);
 	if (ret)
 		goto out_put_vf;
 
@@ -1663,7 +1663,7 @@  ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
 	if (!vf)
 		return -EINVAL;
 
-	ret = ice_check_vf_ready_for_cfg(vf);
+	ret = ice_check_vf_ready_for_reset(vf);
 	if (ret)
 		goto out_put_vf;
 
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
index 0e57bd1b85fd..95878c95e953 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -185,6 +185,25 @@  int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
 	return 0;
 }
 
+/**
+ * ice_check_vf_ready_for_reset - check if VF is ready to be reset
+ * @vf: VF to check if it's ready to be reset
+ *
+ * The purpose of this function is to ensure that the VF is not in reset,
+ * disabled, and is both initialized and active, thus enabling us to safely
+ * initialize another reset.
+ */
+int ice_check_vf_ready_for_reset(struct ice_vf *vf)
+{
+	int ret;
+
+	ret = ice_check_vf_ready_for_cfg(vf);
+	if (!ret && !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
+		ret = -EAGAIN;
+
+	return ret;
+}
+
 /**
  * ice_trigger_vf_reset - Reset a VF on HW
  * @vf: pointer to the VF structure
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
index ef30f05b5d02..3fc6a0a8d955 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
@@ -215,6 +215,7 @@  u16 ice_get_num_vfs(struct ice_pf *pf);
 struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
 bool ice_is_vf_disabled(struct ice_vf *vf);
 int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
+int ice_check_vf_ready_for_reset(struct ice_vf *vf);
 void ice_set_vf_state_dis(struct ice_vf *vf);
 bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);
 void
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
index e24e3f5017ca..d8c66baf4eb4 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
@@ -3908,6 +3908,7 @@  void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
 		ice_vc_notify_vf_link_state(vf);
 		break;
 	case VIRTCHNL_OP_RESET_VF:
+		clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
 		ops->reset_vf(vf);
 		break;
 	case VIRTCHNL_OP_ADD_ETH_ADDR: