Skip to content

Commit 0bd2c61

Browse files
chiarameiohasrleon
authored andcommitted
RDMA/mlx5: Ensure active slave attachment to the bond IB device
Fix a race condition when creating a lag bond in active backup mode where after the bond creation the backup slave was attached to the IB device, instead of the active slave. This caused stale entries in the GID table, as the gid updating mechanism relies on ib_device_get_netdev(), which would return the backup slave. Send an MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE event when activating the lag, additionally to when modifying the lag. This ensures that eventually the active netdevice is stored in the bond IB device. When handling this event remove the GIDs of the previously attached netdevice in this port and rescan the GIDs of the newly attached netdevice. This ensures that eventually the active slave netdevice is correctly stored in the IB device port. While there might be a brief moment where the backup slave GIDs appear in the GID table, it will eventually stabilize with the correct GIDs (of the bond and the active slave). Fixes: 8d159eb ("RDMA/mlx5: Use IB set_netdev and get_netdev functions") Signed-off-by: Chiara Meiohas <[email protected]> Link: https://patch.msgid.link/91fc2cb24f63add266a528c1c702668a80416d9f.1730381292.git.leon@kernel.org Signed-off-by: Leon Romanovsky <[email protected]>
1 parent af7a35b commit 0bd2c61

File tree

2 files changed

+29
-10
lines changed
  • drivers
    • infiniband/hw/mlx5
    • net/ethernet/mellanox/mlx5/core/lag

2 files changed

+29
-10
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3219,12 +3219,14 @@ static int lag_event(struct notifier_block *nb, unsigned long event, void *data)
32193219
struct mlx5_ib_dev *dev = container_of(nb, struct mlx5_ib_dev,
32203220
lag_events);
32213221
struct mlx5_core_dev *mdev = dev->mdev;
3222+
struct ib_device *ibdev = &dev->ib_dev;
3223+
struct net_device *old_ndev = NULL;
32223224
struct mlx5_ib_port *port;
32233225
struct net_device *ndev;
3224-
int i, err;
3225-
int portnum;
3226+
u32 portnum = 0;
3227+
int ret = 0;
3228+
int i;
32263229

3227-
portnum = 0;
32283230
switch (event) {
32293231
case MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE:
32303232
ndev = data;
@@ -3240,18 +3242,24 @@ static int lag_event(struct notifier_block *nb, unsigned long event, void *data)
32403242
}
32413243
}
32423244
}
3243-
err = ib_device_set_netdev(&dev->ib_dev, ndev,
3244-
portnum + 1);
3245-
if (err)
3246-
return err;
3247-
/* Rescan gids after new netdev assignment */
3248-
rdma_roce_rescan_device(&dev->ib_dev);
3245+
old_ndev = ib_device_get_netdev(ibdev, portnum + 1);
3246+
ret = ib_device_set_netdev(ibdev, ndev, portnum + 1);
3247+
if (ret)
3248+
goto out;
3249+
3250+
if (old_ndev)
3251+
roce_del_all_netdev_gids(ibdev, portnum + 1,
3252+
old_ndev);
3253+
rdma_roce_rescan_port(ibdev, portnum + 1);
32493254
}
32503255
break;
32513256
default:
32523257
return NOTIFY_DONE;
32533258
}
3254-
return NOTIFY_OK;
3259+
3260+
out:
3261+
dev_put(old_ndev);
3262+
return notifier_from_errno(ret);
32553263
}
32563264

32573265
static void mlx5e_lag_event_register(struct mlx5_ib_dev *dev)

drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
919919
{
920920
struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
921921
struct lag_tracker tracker = { };
922+
struct net_device *ndev;
922923
bool do_bond, roce_lag;
923924
int err;
924925
int i;
@@ -982,6 +983,16 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
982983
return;
983984
}
984985
}
986+
if (tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
987+
ndev = mlx5_lag_active_backup_get_netdev(dev0);
988+
/** Only sriov and roce lag should have tracker->TX_type
989+
* set so no need to check the mode
990+
*/
991+
blocking_notifier_call_chain(&dev0->priv.lag_nh,
992+
MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE,
993+
ndev);
994+
dev_put(ndev);
995+
}
985996
} else if (mlx5_lag_should_modify_lag(ldev, do_bond)) {
986997
mlx5_modify_lag(ldev, &tracker);
987998
} else if (mlx5_lag_should_disable_lag(ldev, do_bond)) {

0 commit comments

Comments
 (0)