diff mbox series

[net,03/15] net/mlx5: E-switch, Fix duplicate lag creation

Message ID 20221124081040.171790-4-saeed@kernel.org (mailing list archive)
State Accepted
Delegated to: Netdev Maintainers
Headers show
Series [net,01/15] net/mlx5: DR, Fix uninitialized var warning | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Pull request is its own cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1 this patch: 1
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1 this patch: 1
netdev/checkpatch warning WARNING: line length of 92 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0

Commit Message

Saeed Mahameed Nov. 24, 2022, 8:10 a.m. UTC
From: Chris Mi <cmi@nvidia.com>

If creating bond first and then enabling sriov in switchdev mode,
will hit the following syndrome:

mlx5_core 0000:08:00.0: mlx5_cmd_out_err:778:(pid 25543): CREATE_LAG(0x840) op_mod(0x0) failed, status bad parameter(0x3), syndrome (0x7d49cb), err(-22)

The reason is because the offending patch removes eswitch mode
none. In vf lag, the checking of eswitch mode none is replaced
by checking if sriov is enabled. But when driver enables sriov,
it triggers the bond workqueue task first and then setting sriov
number in pci_enable_sriov(). So the check fails.

Fix it by checking if sriov is enabled using eswitch internal
counter that is set before triggering the bond workqueue task.

Fixes: f019679ea5f2 ("net/mlx5: E-switch, Remove dependency between sriov and eswitch mode")
Signed-off-by: Chris Mi <cmi@nvidia.com>
Reviewed-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Reviewed-by: Vlad Buslov <vladbu@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 8 ++++++++
 drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 5 +++--
 2 files changed, 11 insertions(+), 2 deletions(-)

Comments

Keller, Jacob E Nov. 28, 2022, 11:23 p.m. UTC | #1
On 11/24/2022 12:10 AM, Saeed Mahameed wrote:
> From: Chris Mi <cmi@nvidia.com>
> 
> If creating bond first and then enabling sriov in switchdev mode,
> will hit the following syndrome:
> 
> mlx5_core 0000:08:00.0: mlx5_cmd_out_err:778:(pid 25543): CREATE_LAG(0x840) op_mod(0x0) failed, status bad parameter(0x3), syndrome (0x7d49cb), err(-22)
> 
> The reason is because the offending patch removes eswitch mode
> none. In vf lag, the checking of eswitch mode none is replaced
> by checking if sriov is enabled. But when driver enables sriov,
> it triggers the bond workqueue task first and then setting sriov
> number in pci_enable_sriov(). So the check fails.
> 
> Fix it by checking if sriov is enabled using eswitch internal
> counter that is set before triggering the bond workqueue task.
> 
> Fixes: f019679ea5f2 ("net/mlx5: E-switch, Remove dependency between sriov and eswitch mode")
> Signed-off-by: Chris Mi <cmi@nvidia.com>
> Reviewed-by: Roi Dayan <roid@nvidia.com>
> Reviewed-by: Mark Bloch <mbloch@nvidia.com>
> Reviewed-by: Vlad Buslov <vladbu@nvidia.com>
> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
> ---
>   drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 8 ++++++++
>   drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 5 +++--
>   2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
> index f68dc2d0dbe6..3029bc1c0dd0 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
> @@ -736,6 +736,14 @@ void mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
>   					      struct mlx5_eswitch *slave_esw);
>   int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
>   
> +static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
> +{
> +	if (mlx5_esw_allowed(esw))
> +		return esw->esw_funcs.num_vfs;
> +
> +	return 0;
> +}
> +
>   #else  /* CONFIG_MLX5_ESWITCH */
>   /* eswitch API stubs */
>   static inline int  mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> index be1307a63e6d..4070dc1d17cb 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> @@ -701,8 +701,9 @@ static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
>   
>   #ifdef CONFIG_MLX5_ESWITCH
>   	dev = ldev->pf[MLX5_LAG_P1].dev;
> -	if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev))
> -		return false;
> +	for (i = 0; i  < ldev->ports; i++)
> +		if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
> +			return false;
>   

Am I missing something? whats with the for loop iterator here? i isn't 
used or passed into these functions?

Do you need to check multiple times or do these functions have some side 
effect? But looking at their implementation neither of them appear to 
have side effects?

What am I missing?

Shouldn't this just be:
>> -	if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev) >> +	if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && 
!is_mdev_switchdev_mode(dev))
>>  		return false;
Saeed Mahameed Nov. 29, 2022, 5:51 a.m. UTC | #2
On 28 Nov 15:23, Jacob Keller wrote:
>
>
>On 11/24/2022 12:10 AM, Saeed Mahameed wrote:
>>From: Chris Mi <cmi@nvidia.com>
>>
>>If creating bond first and then enabling sriov in switchdev mode,
>>will hit the following syndrome:
>>
>>mlx5_core 0000:08:00.0: mlx5_cmd_out_err:778:(pid 25543): CREATE_LAG(0x840) op_mod(0x0) failed, status bad parameter(0x3), syndrome (0x7d49cb), err(-22)
>>
>>The reason is because the offending patch removes eswitch mode
>>none. In vf lag, the checking of eswitch mode none is replaced
>>by checking if sriov is enabled. But when driver enables sriov,
>>it triggers the bond workqueue task first and then setting sriov
>>number in pci_enable_sriov(). So the check fails.
>>
>>Fix it by checking if sriov is enabled using eswitch internal
>>counter that is set before triggering the bond workqueue task.
>>
>>Fixes: f019679ea5f2 ("net/mlx5: E-switch, Remove dependency between sriov and eswitch mode")
>>Signed-off-by: Chris Mi <cmi@nvidia.com>
>>Reviewed-by: Roi Dayan <roid@nvidia.com>
>>Reviewed-by: Mark Bloch <mbloch@nvidia.com>
>>Reviewed-by: Vlad Buslov <vladbu@nvidia.com>
>>Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
>>---
>>  drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 8 ++++++++
>>  drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 5 +++--
>>  2 files changed, 11 insertions(+), 2 deletions(-)
>>

[...]

>>diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
>>index be1307a63e6d..4070dc1d17cb 100644
>>--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
>>+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
>>@@ -701,8 +701,9 @@ static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
>>  #ifdef CONFIG_MLX5_ESWITCH
>>  	dev = ldev->pf[MLX5_LAG_P1].dev;
>>-	if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev))
>>-		return false;
>>+	for (i = 0; i  < ldev->ports; i++)
>>+		if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
>>+			return false;
>
>Am I missing something? whats with the for loop iterator here? i isn't 
>used or passed into these functions?
>
>Do you need to check multiple times or do these functions have some 
>side effect? But looking at their implementation neither of them 
>appear to have side effects?
>
>What am I missing?

Great catch! it's a copy/paste bug, here we need to grab each port's
eswitch on every iteration.

something like:
for (i = 0; i  < ldev->ports; i++) {
+     dev = ldev->pf[i].dev;
      if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
              return false;
}
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index f68dc2d0dbe6..3029bc1c0dd0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -736,6 +736,14 @@  void mlx5_eswitch_offloads_destroy_single_fdb(struct mlx5_eswitch *master_esw,
 					      struct mlx5_eswitch *slave_esw);
 int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
 
+static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
+{
+	if (mlx5_esw_allowed(esw))
+		return esw->esw_funcs.num_vfs;
+
+	return 0;
+}
+
 #else  /* CONFIG_MLX5_ESWITCH */
 /* eswitch API stubs */
 static inline int  mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
index be1307a63e6d..4070dc1d17cb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -701,8 +701,9 @@  static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
 
 #ifdef CONFIG_MLX5_ESWITCH
 	dev = ldev->pf[MLX5_LAG_P1].dev;
-	if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev))
-		return false;
+	for (i = 0; i  < ldev->ports; i++)
+		if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
+			return false;
 
 	mode = mlx5_eswitch_mode(dev);
 	for (i = 0; i < ldev->ports; i++)