# Re: \[PATCH net-next V3 10/15\] net/mlx5: LAG, disable both regular and SD LAG on lag\_disable\_change

- From: Shay Drori \<hidden\>
- Date: 2026-06-14 16:43:50 
- List: netdev
- Page: https://ratatoskr.run/netdev/2026/06/17130600
- Thread: https://ratatoskr.run/netdev/2026/06/17125048/t.md

```text


On 12/06/2026 14:38, Tariq Toukan wrote:
> From: Shay Drory <redacted>
>
> Extend mlx5_lag_disable_change() to properly disable both regular LAG
> and SD LAG when requested. Each LAG type uses its own devcom component
> for locking.
>
> Use mlx5_sd_get_devcom() helper to retrieve the SD devcom component,
> needed for proper locking when disabling SD LAG.
>
> Signed-off-by: Shay Drory <redacted>
> Reviewed-by: Mark Bloch <mbloch@nvidia.com>
> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
> ---
>   .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 29 +++++++++++++++++--
>   1 file changed, 27 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 e23c1e81b98f..84eff995cad1 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> @@ -2494,13 +2494,22 @@ EXPORT_SYMBOL(mlx5_lag_is_shared_fdb);
>   
>   void mlx5_lag_disable_change(struct mlx5_core_dev *dev)
>   {
> +	struct mlx5_devcom_comp_dev *sd_devcom = mlx5_sd_get_devcom(dev);
> +	struct mlx5_core_dev *primary = dev;
>   	struct mlx5_lag *ldev;
> +	struct lag_func *pf;
> +	int i;
>   
>   	ldev = mlx5_lag_dev(dev);
>   	if (!ldev)
>   		return;
>   
> -	mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp);
> +	if (sd_devcom) {
> +		mlx5_devcom_comp_lock(sd_devcom);
> +		primary = mlx5_sd_get_primary(dev) ?: dev;
> +		mlx5_devcom_comp_unlock(sd_devcom);
> +	}
> +	mlx5_devcom_comp_lock(primary->priv.hca_devcom_comp);
>   	mutex_lock(&ldev->lock);
>   
>   	ldev->mode_changes_in_progress++;
> @@ -2512,7 +2521,23 @@ void mlx5_lag_disable_change(struct mlx5_core_dev *dev)
>   	}
>   
>   	mutex_unlock(&ldev->lock);
> -	mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp);
> +	mlx5_devcom_comp_unlock(primary->priv.hca_devcom_comp);
> +
> +	if (!sd_devcom)
> +		return;
> +
> +	/* Teardown SD shared FDB for this device's group if active */
> +	mlx5_devcom_comp_lock(sd_devcom);
> +	mutex_lock(&ldev->lock);
> +	mlx5_lag_for_each(i, 0, ldev, MLX5_LAG_FILTER_ALL) {
> +		pf = mlx5_lag_pf(ldev, i);
> +		if (pf->dev == dev && pf->sd_fdb_active) {
> +			mlx5_lag_shared_fdb_destroy(ldev, pf->group_id);
> +			break;
> +		}
> +	}
> +	mutex_unlock(&ldev->lock);
> +	mlx5_devcom_comp_unlock(sd_devcom);

sashiko.dev says:
Does holding the sd_devcom lock while calling mlx5_lag_shared_fdb_destroy()
introduce an AB-BA deadlock with auxiliary device probe?
This path acquires sd_devcom, and mlx5_lag_shared_fdb_destroy() eventually
reaches mlx5_rescan_drivers_locked() calling device_del() on auxiliary
devices, which attempts to acquire device_lock(&adev->dev). This gives us:
sd_devcom -> device_lock()
However, during auxiliary device probe, the driver core holds
device_lock(&adev->dev) before calling mlx5e_probe().
mlx5e_probe() then calls mlx5_sd_get_adev() which acquires sd_devcom,
giving us the reverse:
device_lock() -> sd_devcom
Could the teardown be performed without holding the sd_devcom lock here
to prevent this deadlock?

[SD] No — the teardown's device_del runs on the IB aux devices, while
the device_lock held during probe is the ETH aux device (mlx5e_probe);
different struct devices, so no AB-BA

>   }
>   
>   void mlx5_lag_enable_change(struct mlx5_core_dev *dev)

```
