Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/mlx5: Move the SF table notifiers outside the devlink lock

Move the SF table notifiers registration/unregistration outside of
mlx5_init_one() / mlx5_uninit_one() and into the mlx5_mdev_init() /
mlx5_mdev_uninit() functions.

This is only done for non-SFs, since SFs do not have a SF table
themselves and thus don't need notifiers.

Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/1763325940-1231508-6-git-send-email-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Cosmin Ratiu and committed by
Jakub Kicinski
d4a0acbd e63c9c5f

+78 -33
+7
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1833 1833 if (err) 1834 1834 goto err_sf_hw_notifier; 1835 1835 1836 + err = mlx5_sf_notifiers_init(dev); 1837 + if (err) 1838 + goto err_sf_notifiers; 1839 + 1836 1840 return 0; 1837 1841 1842 + err_sf_notifiers: 1843 + mlx5_sf_hw_notifier_cleanup(dev); 1838 1844 err_sf_hw_notifier: 1839 1845 mlx5_events_cleanup(dev); 1840 1846 return err; ··· 1848 1842 1849 1843 static void mlx5_notifiers_cleanup(struct mlx5_core_dev *dev) 1850 1844 { 1845 + mlx5_sf_notifiers_cleanup(dev); 1851 1846 mlx5_sf_hw_notifier_cleanup(dev); 1852 1847 mlx5_events_cleanup(dev); 1853 1848 }
+57 -33
drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
··· 31 31 struct mlx5_core_dev *dev; /* To refer from notifier context. */ 32 32 struct xarray function_ids; /* function id based lookup. */ 33 33 struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */ 34 - struct notifier_block esw_nb; 35 - struct notifier_block vhca_nb; 36 - struct notifier_block mdev_nb; 37 34 }; 38 35 39 36 static struct mlx5_sf * ··· 388 391 389 392 static int mlx5_sf_vhca_event(struct notifier_block *nb, unsigned long opcode, void *data) 390 393 { 391 - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, vhca_nb); 394 + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, 395 + priv.sf_table_vhca_nb); 396 + struct mlx5_sf_table *table = dev->priv.sf_table; 392 397 const struct mlx5_vhca_state_event *event = data; 393 398 bool update = false; 394 399 struct mlx5_sf *sf; 400 + 401 + if (!table) 402 + return 0; 395 403 396 404 mutex_lock(&table->sf_state_lock); 397 405 sf = mlx5_sf_lookup_by_function_id(table, event->function_id); ··· 409 407 update = mlx5_sf_state_update_check(sf, event->new_vhca_state); 410 408 if (update) 411 409 sf->hw_state = event->new_vhca_state; 412 - trace_mlx5_sf_update_state(table->dev, sf->port_index, sf->controller, 410 + trace_mlx5_sf_update_state(dev, sf->port_index, sf->controller, 413 411 sf->hw_fn_id, sf->hw_state); 414 412 unlock: 415 413 mutex_unlock(&table->sf_state_lock); ··· 427 425 428 426 static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, void *data) 429 427 { 430 - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, esw_nb); 428 + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, 429 + priv.sf_table_esw_nb); 431 430 const struct mlx5_esw_event_info *mode = data; 431 + 432 + if (!dev->priv.sf_table) 433 + return 0; 432 434 433 435 switch (mode->new_mode) { 434 436 case MLX5_ESWITCH_LEGACY: 435 - mlx5_sf_del_all(table); 437 + mlx5_sf_del_all(dev->priv.sf_table); 436 438 break; 437 439 default: 438 440 break; ··· 447 441 448 442 static int mlx5_sf_mdev_event(struct notifier_block *nb, unsigned long event, void *data) 449 443 { 450 - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, mdev_nb); 444 + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, 445 + priv.sf_table_mdev_nb); 451 446 struct mlx5_sf_peer_devlink_event_ctx *event_ctx = data; 447 + struct mlx5_sf_table *table = dev->priv.sf_table; 452 448 int ret = NOTIFY_DONE; 453 449 struct mlx5_sf *sf; 454 450 455 - if (event != MLX5_DRIVER_EVENT_SF_PEER_DEVLINK) 451 + if (!table || event != MLX5_DRIVER_EVENT_SF_PEER_DEVLINK) 456 452 return NOTIFY_DONE; 457 - 458 453 459 454 mutex_lock(&table->sf_state_lock); 460 455 sf = mlx5_sf_lookup_by_function_id(table, event_ctx->fn_id); ··· 471 464 return ret; 472 465 } 473 466 467 + int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev) 468 + { 469 + int err; 470 + 471 + if (mlx5_core_is_sf(dev)) 472 + return 0; 473 + 474 + dev->priv.sf_table_esw_nb.notifier_call = mlx5_sf_esw_event; 475 + err = mlx5_esw_event_notifier_register(dev, &dev->priv.sf_table_esw_nb); 476 + if (err) 477 + return err; 478 + 479 + dev->priv.sf_table_vhca_nb.notifier_call = mlx5_sf_vhca_event; 480 + err = mlx5_vhca_event_notifier_register(dev, 481 + &dev->priv.sf_table_vhca_nb); 482 + if (err) 483 + goto vhca_err; 484 + 485 + dev->priv.sf_table_mdev_nb.notifier_call = mlx5_sf_mdev_event; 486 + err = mlx5_blocking_notifier_register(dev, &dev->priv.sf_table_mdev_nb); 487 + if (err) 488 + goto mdev_err; 489 + 490 + return 0; 491 + mdev_err: 492 + mlx5_vhca_event_notifier_unregister(dev, &dev->priv.sf_table_vhca_nb); 493 + vhca_err: 494 + mlx5_esw_event_notifier_unregister(dev, &dev->priv.sf_table_esw_nb); 495 + return err; 496 + } 497 + 474 498 int mlx5_sf_table_init(struct mlx5_core_dev *dev) 475 499 { 476 500 struct mlx5_sf_table *table; 477 - int err; 478 501 479 502 if (!mlx5_sf_table_supported(dev) || !mlx5_vhca_event_supported(dev)) 480 503 return 0; ··· 517 480 table->dev = dev; 518 481 xa_init(&table->function_ids); 519 482 dev->priv.sf_table = table; 520 - table->esw_nb.notifier_call = mlx5_sf_esw_event; 521 - err = mlx5_esw_event_notifier_register(dev, &table->esw_nb); 522 - if (err) 523 - goto reg_err; 524 - 525 - table->vhca_nb.notifier_call = mlx5_sf_vhca_event; 526 - err = mlx5_vhca_event_notifier_register(table->dev, &table->vhca_nb); 527 - if (err) 528 - goto vhca_err; 529 - 530 - table->mdev_nb.notifier_call = mlx5_sf_mdev_event; 531 - mlx5_blocking_notifier_register(dev, &table->mdev_nb); 532 483 533 484 return 0; 485 + } 534 486 535 - vhca_err: 536 - mlx5_esw_event_notifier_unregister(dev, &table->esw_nb); 537 - reg_err: 538 - mutex_destroy(&table->sf_state_lock); 539 - kfree(table); 540 - dev->priv.sf_table = NULL; 541 - return err; 487 + void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev) 488 + { 489 + if (mlx5_core_is_sf(dev)) 490 + return; 491 + 492 + mlx5_blocking_notifier_unregister(dev, &dev->priv.sf_table_mdev_nb); 493 + mlx5_vhca_event_notifier_unregister(dev, &dev->priv.sf_table_vhca_nb); 494 + mlx5_esw_event_notifier_unregister(dev, &dev->priv.sf_table_esw_nb); 542 495 } 543 496 544 497 void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) ··· 538 511 if (!table) 539 512 return; 540 513 541 - mlx5_blocking_notifier_unregister(dev, &table->mdev_nb); 542 - mlx5_vhca_event_notifier_unregister(table->dev, &table->vhca_nb); 543 - mlx5_esw_event_notifier_unregister(dev, &table->esw_nb); 544 514 mutex_destroy(&table->sf_state_lock); 545 515 WARN_ON(!xa_empty(&table->function_ids)); 546 516 kfree(table);
+11
drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
··· 16 16 void mlx5_sf_hw_notifier_cleanup(struct mlx5_core_dev *dev); 17 17 void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev); 18 18 19 + int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev); 19 20 int mlx5_sf_table_init(struct mlx5_core_dev *dev); 21 + void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev); 20 22 void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev); 21 23 bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev); 22 24 ··· 60 58 { 61 59 } 62 60 61 + static inline int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev) 62 + { 63 + return 0; 64 + } 65 + 63 66 static inline int mlx5_sf_table_init(struct mlx5_core_dev *dev) 64 67 { 65 68 return 0; 69 + } 70 + 71 + static inline void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev) 72 + { 66 73 } 67 74 68 75 static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+3
include/linux/mlx5/driver.h
··· 622 622 #ifdef CONFIG_MLX5_SF_MANAGER 623 623 struct notifier_block sf_hw_table_vhca_nb; 624 624 struct mlx5_sf_hw_table *sf_hw_table; 625 + struct notifier_block sf_table_esw_nb; 626 + struct notifier_block sf_table_vhca_nb; 627 + struct notifier_block sf_table_mdev_nb; 625 628 struct mlx5_sf_table *sf_table; 626 629 #endif 627 630 struct blocking_notifier_head lag_nh;