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

net/mlx5: Move the SF HW table notifier outside the devlink lock

Move the SF HW table notifier 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 HW table
themselves.

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-5-git-send-email-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Cosmin Ratiu and committed by
Jakub Kicinski
e63c9c5f d3a356db

+54 -35
+9 -8
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1377 1377 1378 1378 mlx5_vhca_event_start(dev); 1379 1379 1380 - err = mlx5_sf_hw_table_create(dev); 1381 - if (err) { 1382 - mlx5_core_err(dev, "sf table create failed %d\n", err); 1383 - goto err_vhca; 1384 - } 1385 - 1386 1380 err = mlx5_ec_init(dev); 1387 1381 if (err) { 1388 1382 mlx5_core_err(dev, "Failed to init embedded CPU\n"); ··· 1405 1411 mlx5_lag_remove_mdev(dev); 1406 1412 mlx5_ec_cleanup(dev); 1407 1413 err_ec: 1408 - mlx5_sf_hw_table_destroy(dev); 1409 - err_vhca: 1410 1414 mlx5_vhca_event_stop(dev); 1411 1415 err_set_hca: 1412 1416 mlx5_fs_core_cleanup(dev); ··· 1829 1837 BLOCKING_INIT_NOTIFIER_HEAD(&dev->priv.esw_n_head); 1830 1838 mlx5_vhca_state_notifier_init(dev); 1831 1839 1840 + err = mlx5_sf_hw_notifier_init(dev); 1841 + if (err) 1842 + goto err_sf_hw_notifier; 1843 + 1832 1844 return 0; 1845 + 1846 + err_sf_hw_notifier: 1847 + mlx5_events_cleanup(dev); 1848 + return err; 1833 1849 } 1834 1850 1835 1851 static void mlx5_notifiers_cleanup(struct mlx5_core_dev *dev) 1836 1852 { 1853 + mlx5_sf_hw_notifier_cleanup(dev); 1837 1854 mlx5_events_cleanup(dev); 1838 1855 } 1839 1856
+37 -25
drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c
··· 30 30 }; 31 31 32 32 struct mlx5_sf_hw_table { 33 - struct mlx5_core_dev *dev; 34 33 struct mutex table_lock; /* Serializes sf deletion and vhca state change handler. */ 35 - struct notifier_block vhca_nb; 36 34 struct mlx5_sf_hwc_table hwc[MLX5_SF_HWC_MAX]; 37 35 }; 38 36 ··· 69 71 return NULL; 70 72 } 71 73 72 - static int mlx5_sf_hw_table_id_alloc(struct mlx5_sf_hw_table *table, u32 controller, 74 + static int mlx5_sf_hw_table_id_alloc(struct mlx5_core_dev *dev, 75 + struct mlx5_sf_hw_table *table, 76 + u32 controller, 73 77 u32 usr_sfnum) 74 78 { 75 79 struct mlx5_sf_hwc_table *hwc; 76 80 int free_idx = -1; 77 81 int i; 78 82 79 - hwc = mlx5_sf_controller_to_hwc(table->dev, controller); 83 + hwc = mlx5_sf_controller_to_hwc(dev, controller); 80 84 if (!hwc->sfs) 81 85 return -ENOSPC; 82 86 ··· 100 100 return free_idx; 101 101 } 102 102 103 - static void mlx5_sf_hw_table_id_free(struct mlx5_sf_hw_table *table, u32 controller, int id) 103 + static void mlx5_sf_hw_table_id_free(struct mlx5_core_dev *dev, 104 + struct mlx5_sf_hw_table *table, 105 + u32 controller, int id) 104 106 { 105 107 struct mlx5_sf_hwc_table *hwc; 106 108 107 - hwc = mlx5_sf_controller_to_hwc(table->dev, controller); 109 + hwc = mlx5_sf_controller_to_hwc(dev, controller); 108 110 hwc->sfs[id].allocated = false; 109 111 hwc->sfs[id].pending_delete = false; 110 112 } ··· 122 120 return -EOPNOTSUPP; 123 121 124 122 mutex_lock(&table->table_lock); 125 - sw_id = mlx5_sf_hw_table_id_alloc(table, controller, usr_sfnum); 123 + sw_id = mlx5_sf_hw_table_id_alloc(dev, table, controller, usr_sfnum); 126 124 if (sw_id < 0) { 127 125 err = sw_id; 128 126 goto exist_err; ··· 153 151 vhca_err: 154 152 mlx5_cmd_dealloc_sf(dev, hw_fn_id); 155 153 err: 156 - mlx5_sf_hw_table_id_free(table, controller, sw_id); 154 + mlx5_sf_hw_table_id_free(dev, table, controller, sw_id); 157 155 exist_err: 158 156 mutex_unlock(&table->table_lock); 159 157 return err; ··· 167 165 mutex_lock(&table->table_lock); 168 166 hw_fn_id = mlx5_sf_sw_to_hw_id(dev, controller, id); 169 167 mlx5_cmd_dealloc_sf(dev, hw_fn_id); 170 - mlx5_sf_hw_table_id_free(table, controller, id); 168 + mlx5_sf_hw_table_id_free(dev, table, controller, id); 171 169 mutex_unlock(&table->table_lock); 172 170 } 173 171 ··· 218 216 } 219 217 } 220 218 221 - static void mlx5_sf_hw_table_dealloc_all(struct mlx5_sf_hw_table *table) 219 + static void mlx5_sf_hw_table_dealloc_all(struct mlx5_core_dev *dev, 220 + struct mlx5_sf_hw_table *table) 222 221 { 223 - mlx5_sf_hw_table_hwc_dealloc_all(table->dev, &table->hwc[MLX5_SF_HWC_EXTERNAL]); 224 - mlx5_sf_hw_table_hwc_dealloc_all(table->dev, &table->hwc[MLX5_SF_HWC_LOCAL]); 222 + mlx5_sf_hw_table_hwc_dealloc_all(dev, 223 + &table->hwc[MLX5_SF_HWC_EXTERNAL]); 224 + mlx5_sf_hw_table_hwc_dealloc_all(dev, &table->hwc[MLX5_SF_HWC_LOCAL]); 225 225 } 226 226 227 227 static int mlx5_sf_hw_table_hwc_init(struct mlx5_sf_hwc_table *hwc, u16 max_fn, u16 base_id) ··· 305 301 } 306 302 307 303 mutex_init(&table->table_lock); 308 - table->dev = dev; 309 304 dev->priv.sf_hw_table = table; 310 305 311 306 base_id = mlx5_sf_start_function_id(dev); ··· 341 338 mlx5_sf_hw_table_hwc_cleanup(&table->hwc[MLX5_SF_HWC_LOCAL]); 342 339 mutex_destroy(&table->table_lock); 343 340 kfree(table); 341 + dev->priv.sf_hw_table = NULL; 344 342 res_unregister: 345 343 mlx5_sf_hw_table_res_unregister(dev); 346 344 } 347 345 348 346 static int mlx5_sf_hw_vhca_event(struct notifier_block *nb, unsigned long opcode, void *data) 349 347 { 350 - struct mlx5_sf_hw_table *table = container_of(nb, struct mlx5_sf_hw_table, vhca_nb); 348 + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, 349 + priv.sf_hw_table_vhca_nb); 350 + struct mlx5_sf_hw_table *table = dev->priv.sf_hw_table; 351 351 const struct mlx5_vhca_state_event *event = data; 352 352 struct mlx5_sf_hwc_table *hwc; 353 353 struct mlx5_sf_hw *sf_hw; 354 354 u16 sw_id; 355 355 356 - if (event->new_vhca_state != MLX5_VHCA_STATE_ALLOCATED) 356 + if (!table || event->new_vhca_state != MLX5_VHCA_STATE_ALLOCATED) 357 357 return 0; 358 358 359 359 hwc = mlx5_sf_table_fn_to_hwc(table, event->function_id); ··· 371 365 * Hence recycle the sf hardware id for reuse. 372 366 */ 373 367 if (sf_hw->allocated && sf_hw->pending_delete) 374 - mlx5_sf_hw_table_hwc_sf_free(table->dev, hwc, sw_id); 368 + mlx5_sf_hw_table_hwc_sf_free(dev, hwc, sw_id); 375 369 mutex_unlock(&table->table_lock); 376 370 return 0; 377 371 } 378 372 379 - int mlx5_sf_hw_table_create(struct mlx5_core_dev *dev) 373 + int mlx5_sf_hw_notifier_init(struct mlx5_core_dev *dev) 380 374 { 381 - struct mlx5_sf_hw_table *table = dev->priv.sf_hw_table; 382 - 383 - if (!table) 375 + if (mlx5_core_is_sf(dev)) 384 376 return 0; 385 377 386 - table->vhca_nb.notifier_call = mlx5_sf_hw_vhca_event; 387 - return mlx5_vhca_event_notifier_register(dev, &table->vhca_nb); 378 + dev->priv.sf_hw_table_vhca_nb.notifier_call = mlx5_sf_hw_vhca_event; 379 + return mlx5_vhca_event_notifier_register(dev, 380 + &dev->priv.sf_hw_table_vhca_nb); 381 + } 382 + 383 + void mlx5_sf_hw_notifier_cleanup(struct mlx5_core_dev *dev) 384 + { 385 + if (mlx5_core_is_sf(dev)) 386 + return; 387 + 388 + mlx5_vhca_event_notifier_unregister(dev, 389 + &dev->priv.sf_hw_table_vhca_nb); 388 390 } 389 391 390 392 void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev) ··· 402 388 if (!table) 403 389 return; 404 390 405 - mlx5_vhca_event_notifier_unregister(dev, &table->vhca_nb); 406 - 407 391 /* Dealloc SFs whose firmware event has been missed. */ 408 - mlx5_sf_hw_table_dealloc_all(table); 392 + mlx5_sf_hw_table_dealloc_all(dev, table); 409 393 } 410 394 411 395 bool mlx5_sf_hw_table_supported(const struct mlx5_core_dev *dev)
+7 -2
drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
··· 12 12 int mlx5_sf_hw_table_init(struct mlx5_core_dev *dev); 13 13 void mlx5_sf_hw_table_cleanup(struct mlx5_core_dev *dev); 14 14 15 - int mlx5_sf_hw_table_create(struct mlx5_core_dev *dev); 15 + int mlx5_sf_hw_notifier_init(struct mlx5_core_dev *dev); 16 + void mlx5_sf_hw_notifier_cleanup(struct mlx5_core_dev *dev); 16 17 void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev); 17 18 18 19 int mlx5_sf_table_init(struct mlx5_core_dev *dev); ··· 45 44 { 46 45 } 47 46 48 - static inline int mlx5_sf_hw_table_create(struct mlx5_core_dev *dev) 47 + static inline int mlx5_sf_hw_notifier_init(struct mlx5_core_dev *dev) 49 48 { 50 49 return 0; 50 + } 51 + 52 + static inline void mlx5_sf_hw_notifier_cleanup(struct mlx5_core_dev *dev) 53 + { 51 54 } 52 55 53 56 static inline void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev)
+1
include/linux/mlx5/driver.h
··· 620 620 struct mlx5_core_dev *parent_mdev; 621 621 #endif 622 622 #ifdef CONFIG_MLX5_SF_MANAGER 623 + struct notifier_block sf_hw_table_vhca_nb; 623 624 struct mlx5_sf_hw_table *sf_hw_table; 624 625 struct mlx5_sf_table *sf_table; 625 626 #endif