Skip to content

Commit 84a433a

Browse files
mosheshemesh2kuba-moo
authored andcommitted
net/mlx5: Lock mlx5 devlink reload callbacks
Change devlink instance locks in mlx5 driver to have devlink reload callbacks locked, while keeping all driver paths which lead to devl_ API functions called by the driver locked. Add mlx5_load_one_devl_locked() and mlx5_unload_one_devl_locked() which are used by the paths which are already locked such as devlink reload callbacks. This patch makes the driver use devl_ API also for traps register as these functions are called from the driver paths parallel to reload that requires locking now. Signed-off-by: Moshe Shemesh <moshe@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c12f4c6 commit 84a433a

File tree

6 files changed

+79
-50
lines changed

6 files changed

+79
-50
lines changed

Diff for: drivers/net/ethernet/mellanox/mlx5/core/dev.c

+4-15
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,12 @@ static void del_adev(struct auxiliary_device *adev)
335335

336336
int mlx5_attach_device(struct mlx5_core_dev *dev)
337337
{
338-
struct devlink *devlink = priv_to_devlink(dev);
339338
struct mlx5_priv *priv = &dev->priv;
340339
struct auxiliary_device *adev;
341340
struct auxiliary_driver *adrv;
342341
int ret = 0, i;
343342

344-
devl_lock(devlink);
343+
devl_assert_locked(priv_to_devlink(dev));
345344
mutex_lock(&mlx5_intf_mutex);
346345
priv->flags &= ~MLX5_PRIV_FLAGS_DETACH;
347346
priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
@@ -394,20 +393,18 @@ int mlx5_attach_device(struct mlx5_core_dev *dev)
394393
}
395394
priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
396395
mutex_unlock(&mlx5_intf_mutex);
397-
devl_unlock(devlink);
398396
return ret;
399397
}
400398

401399
void mlx5_detach_device(struct mlx5_core_dev *dev)
402400
{
403-
struct devlink *devlink = priv_to_devlink(dev);
404401
struct mlx5_priv *priv = &dev->priv;
405402
struct auxiliary_device *adev;
406403
struct auxiliary_driver *adrv;
407404
pm_message_t pm = {};
408405
int i;
409406

410-
devl_lock(devlink);
407+
devl_assert_locked(priv_to_devlink(dev));
411408
mutex_lock(&mlx5_intf_mutex);
412409
priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
413410
for (i = ARRAY_SIZE(mlx5_adev_devices) - 1; i >= 0; i--) {
@@ -441,21 +438,17 @@ void mlx5_detach_device(struct mlx5_core_dev *dev)
441438
priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
442439
priv->flags |= MLX5_PRIV_FLAGS_DETACH;
443440
mutex_unlock(&mlx5_intf_mutex);
444-
devl_unlock(devlink);
445441
}
446442

447443
int mlx5_register_device(struct mlx5_core_dev *dev)
448444
{
449-
struct devlink *devlink;
450445
int ret;
451446

452-
devlink = priv_to_devlink(dev);
453-
devl_lock(devlink);
447+
devl_assert_locked(priv_to_devlink(dev));
454448
mutex_lock(&mlx5_intf_mutex);
455449
dev->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
456450
ret = mlx5_rescan_drivers_locked(dev);
457451
mutex_unlock(&mlx5_intf_mutex);
458-
devl_unlock(devlink);
459452
if (ret)
460453
mlx5_unregister_device(dev);
461454

@@ -464,15 +457,11 @@ int mlx5_register_device(struct mlx5_core_dev *dev)
464457

465458
void mlx5_unregister_device(struct mlx5_core_dev *dev)
466459
{
467-
struct devlink *devlink;
468-
469-
devlink = priv_to_devlink(dev);
470-
devl_lock(devlink);
460+
devl_assert_locked(priv_to_devlink(dev));
471461
mutex_lock(&mlx5_intf_mutex);
472462
dev->priv.flags = MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
473463
mlx5_rescan_drivers_locked(dev);
474464
mutex_unlock(&mlx5_intf_mutex);
475-
devl_unlock(devlink);
476465
}
477466

478467
static int add_drivers(struct mlx5_core_dev *dev)

Diff for: drivers/net/ethernet/mellanox/mlx5/core/devlink.c

+31-19
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
108108
if (err)
109109
return err;
110110

111-
mlx5_unload_one(dev);
111+
mlx5_unload_one_devl_locked(dev);
112112
err = mlx5_health_wait_pci_up(dev);
113113
if (err)
114114
NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
@@ -143,6 +143,7 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
143143
struct mlx5_core_dev *dev = devlink_priv(devlink);
144144
struct pci_dev *pdev = dev->pdev;
145145
bool sf_dev_allocated;
146+
int ret = 0;
146147

147148
sf_dev_allocated = mlx5_sf_dev_allocated(dev);
148149
if (sf_dev_allocated) {
@@ -163,44 +164,55 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
163164
NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
164165
}
165166

167+
devl_lock(devlink);
166168
switch (action) {
167169
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
168-
mlx5_unload_one(dev);
169-
return 0;
170+
mlx5_unload_one_devl_locked(dev);
171+
break;
170172
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
171173
if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
172-
return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
173-
return mlx5_devlink_reload_fw_activate(devlink, extack);
174+
ret = mlx5_devlink_trigger_fw_live_patch(devlink, extack);
175+
else
176+
ret = mlx5_devlink_reload_fw_activate(devlink, extack);
177+
break;
174178
default:
175179
/* Unsupported action should not get to this function */
176180
WARN_ON(1);
177-
return -EOPNOTSUPP;
181+
ret = -EOPNOTSUPP;
178182
}
183+
184+
devl_unlock(devlink);
185+
return ret;
179186
}
180187

181188
static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
182189
enum devlink_reload_limit limit, u32 *actions_performed,
183190
struct netlink_ext_ack *extack)
184191
{
185192
struct mlx5_core_dev *dev = devlink_priv(devlink);
193+
int ret = 0;
186194

195+
devl_lock(devlink);
187196
*actions_performed = BIT(action);
188197
switch (action) {
189198
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
190-
return mlx5_load_one(dev, false);
199+
ret = mlx5_load_one_devl_locked(dev, false);
200+
break;
191201
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
192202
if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
193203
break;
194204
/* On fw_activate action, also driver is reloaded and reinit performed */
195205
*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
196-
return mlx5_load_one(dev, false);
206+
ret = mlx5_load_one_devl_locked(dev, false);
207+
break;
197208
default:
198209
/* Unsupported action should not get to this function */
199210
WARN_ON(1);
200-
return -EOPNOTSUPP;
211+
ret = -EOPNOTSUPP;
201212
}
202213

203-
return 0;
214+
devl_unlock(devlink);
215+
return ret;
204216
}
205217

206218
static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
@@ -837,28 +849,28 @@ static int mlx5_devlink_traps_register(struct devlink *devlink)
837849
struct mlx5_core_dev *core_dev = devlink_priv(devlink);
838850
int err;
839851

840-
err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr,
841-
ARRAY_SIZE(mlx5_trap_groups_arr));
852+
err = devl_trap_groups_register(devlink, mlx5_trap_groups_arr,
853+
ARRAY_SIZE(mlx5_trap_groups_arr));
842854
if (err)
843855
return err;
844856

845-
err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
846-
&core_dev->priv);
857+
err = devl_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
858+
&core_dev->priv);
847859
if (err)
848860
goto err_trap_group;
849861
return 0;
850862

851863
err_trap_group:
852-
devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
853-
ARRAY_SIZE(mlx5_trap_groups_arr));
864+
devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
865+
ARRAY_SIZE(mlx5_trap_groups_arr));
854866
return err;
855867
}
856868

857869
static void mlx5_devlink_traps_unregister(struct devlink *devlink)
858870
{
859-
devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
860-
devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
861-
ARRAY_SIZE(mlx5_trap_groups_arr));
871+
devl_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
872+
devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
873+
ARRAY_SIZE(mlx5_trap_groups_arr));
862874
}
863875

864876
int mlx5_devlink_register(struct devlink *devlink)

Diff for: drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

+4-14
Original file line numberDiff line numberDiff line change
@@ -1300,20 +1300,19 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs)
13001300
*/
13011301
int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
13021302
{
1303-
struct devlink *devlink;
13041303
bool toggle_lag;
13051304
int ret;
13061305

13071306
if (!mlx5_esw_allowed(esw))
13081307
return 0;
13091308

1309+
devl_assert_locked(priv_to_devlink(esw->dev));
1310+
13101311
toggle_lag = !mlx5_esw_is_fdb_created(esw);
13111312

13121313
if (toggle_lag)
13131314
mlx5_lag_disable_change(esw->dev);
13141315

1315-
devlink = priv_to_devlink(esw->dev);
1316-
devl_lock(devlink);
13171316
down_write(&esw->mode_lock);
13181317
if (!mlx5_esw_is_fdb_created(esw)) {
13191318
ret = mlx5_eswitch_enable_locked(esw, num_vfs);
@@ -1327,7 +1326,6 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
13271326
esw->esw_funcs.num_vfs = num_vfs;
13281327
}
13291328
up_write(&esw->mode_lock);
1330-
devl_unlock(devlink);
13311329

13321330
if (toggle_lag)
13331331
mlx5_lag_enable_change(esw->dev);
@@ -1338,13 +1336,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
13381336
/* When disabling sriov, free driver level resources. */
13391337
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
13401338
{
1341-
struct devlink *devlink;
1342-
13431339
if (!mlx5_esw_allowed(esw))
13441340
return;
13451341

1346-
devlink = priv_to_devlink(esw->dev);
1347-
devl_lock(devlink);
1342+
devl_assert_locked(priv_to_devlink(esw->dev));
13481343
down_write(&esw->mode_lock);
13491344
/* If driver is unloaded, this function is called twice by remove_one()
13501345
* and mlx5_unload(). Prevent the second call.
@@ -1373,7 +1368,6 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
13731368

13741369
unlock:
13751370
up_write(&esw->mode_lock);
1376-
devl_unlock(devlink);
13771371
}
13781372

13791373
/* Free resources for corresponding eswitch mode. It is called by devlink
@@ -1407,18 +1401,14 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw)
14071401

14081402
void mlx5_eswitch_disable(struct mlx5_eswitch *esw)
14091403
{
1410-
struct devlink *devlink;
1411-
14121404
if (!mlx5_esw_allowed(esw))
14131405
return;
14141406

1407+
devl_assert_locked(priv_to_devlink(esw->dev));
14151408
mlx5_lag_disable_change(esw->dev);
1416-
devlink = priv_to_devlink(esw->dev);
1417-
devl_lock(devlink);
14181409
down_write(&esw->mode_lock);
14191410
mlx5_eswitch_disable_locked(esw);
14201411
up_write(&esw->mode_lock);
1421-
devl_unlock(devlink);
14221412
mlx5_lag_enable_change(esw->dev);
14231413
}
14241414

Diff for: drivers/net/ethernet/mellanox/mlx5/core/main.c

+32-2
Original file line numberDiff line numberDiff line change
@@ -1304,8 +1304,10 @@ static void mlx5_unload(struct mlx5_core_dev *dev)
13041304

13051305
int mlx5_init_one(struct mlx5_core_dev *dev)
13061306
{
1307+
struct devlink *devlink = priv_to_devlink(dev);
13071308
int err = 0;
13081309

1310+
devl_lock(devlink);
13091311
mutex_lock(&dev->intf_state_mutex);
13101312
dev->state = MLX5_DEVICE_STATE_UP;
13111313

@@ -1334,6 +1336,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
13341336
goto err_register;
13351337

13361338
mutex_unlock(&dev->intf_state_mutex);
1339+
devl_unlock(devlink);
13371340
return 0;
13381341

13391342
err_register:
@@ -1348,11 +1351,15 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
13481351
err_function:
13491352
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
13501353
mutex_unlock(&dev->intf_state_mutex);
1354+
devl_unlock(devlink);
13511355
return err;
13521356
}
13531357

13541358
void mlx5_uninit_one(struct mlx5_core_dev *dev)
13551359
{
1360+
struct devlink *devlink = priv_to_devlink(dev);
1361+
1362+
devl_lock(devlink);
13561363
mutex_lock(&dev->intf_state_mutex);
13571364

13581365
mlx5_unregister_device(dev);
@@ -1371,13 +1378,15 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)
13711378
mlx5_function_teardown(dev, true);
13721379
out:
13731380
mutex_unlock(&dev->intf_state_mutex);
1381+
devl_unlock(devlink);
13741382
}
13751383

1376-
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
1384+
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery)
13771385
{
13781386
int err = 0;
13791387
u64 timeout;
13801388

1389+
devl_assert_locked(priv_to_devlink(dev));
13811390
mutex_lock(&dev->intf_state_mutex);
13821391
if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
13831392
mlx5_core_warn(dev, "interface is up, NOP\n");
@@ -1419,8 +1428,20 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
14191428
return err;
14201429
}
14211430

1422-
void mlx5_unload_one(struct mlx5_core_dev *dev)
1431+
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
14231432
{
1433+
struct devlink *devlink = priv_to_devlink(dev);
1434+
int ret;
1435+
1436+
devl_lock(devlink);
1437+
ret = mlx5_load_one_devl_locked(dev, recovery);
1438+
devl_unlock(devlink);
1439+
return ret;
1440+
}
1441+
1442+
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev)
1443+
{
1444+
devl_assert_locked(priv_to_devlink(dev));
14241445
mutex_lock(&dev->intf_state_mutex);
14251446

14261447
mlx5_detach_device(dev);
@@ -1438,6 +1459,15 @@ void mlx5_unload_one(struct mlx5_core_dev *dev)
14381459
mutex_unlock(&dev->intf_state_mutex);
14391460
}
14401461

1462+
void mlx5_unload_one(struct mlx5_core_dev *dev)
1463+
{
1464+
struct devlink *devlink = priv_to_devlink(dev);
1465+
1466+
devl_lock(devlink);
1467+
mlx5_unload_one_devl_locked(dev);
1468+
devl_unlock(devlink);
1469+
}
1470+
14411471
static const int types[] = {
14421472
MLX5_CAP_GENERAL,
14431473
MLX5_CAP_GENERAL_2,

Diff for: drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h

+2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,9 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev);
290290
int mlx5_init_one(struct mlx5_core_dev *dev);
291291
void mlx5_uninit_one(struct mlx5_core_dev *dev);
292292
void mlx5_unload_one(struct mlx5_core_dev *dev);
293+
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev);
293294
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery);
295+
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery);
294296

295297
int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out);
296298

0 commit comments

Comments
 (0)