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

net/mlx5: Move SF dev table notifier registration outside the PF devlink lock

This completes the previous patches by moving notifier registration for
SF dev tables outside the devlink locked critical section in
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.

After this patch, notifiers can grab the PF devlink lock (soon to be
necessary) without creating a locking cycle.

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

authored by

Cosmin Ratiu and committed by
Jakub Kicinski
64ad6470 d4a0acbd

+49 -17
+7
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1837 1837 if (err) 1838 1838 goto err_sf_notifiers; 1839 1839 1840 + err = mlx5_sf_dev_notifier_init(dev); 1841 + if (err) 1842 + goto err_sf_dev_notifier; 1843 + 1840 1844 return 0; 1841 1845 1846 + err_sf_dev_notifier: 1847 + mlx5_sf_notifiers_cleanup(dev); 1842 1848 err_sf_notifiers: 1843 1849 mlx5_sf_hw_notifier_cleanup(dev); 1844 1850 err_sf_hw_notifier: ··· 1854 1848 1855 1849 static void mlx5_notifiers_cleanup(struct mlx5_core_dev *dev) 1856 1850 { 1851 + mlx5_sf_dev_notifier_cleanup(dev); 1857 1852 mlx5_sf_notifiers_cleanup(dev); 1858 1853 mlx5_sf_hw_notifier_cleanup(dev); 1859 1854 mlx5_events_cleanup(dev);
+30 -17
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
··· 16 16 struct xarray devices; 17 17 phys_addr_t base_address; 18 18 u64 sf_bar_length; 19 - struct notifier_block nb; 20 19 struct workqueue_struct *active_wq; 21 20 struct work_struct work; 22 21 u8 stop_active_wq:1; ··· 155 156 static int 156 157 mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_code, void *data) 157 158 { 158 - struct mlx5_sf_dev_table *table = container_of(nb, struct mlx5_sf_dev_table, nb); 159 + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, 160 + priv.sf_dev_nb); 161 + struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; 159 162 const struct mlx5_vhca_state_event *event = data; 160 163 struct mlx5_sf_dev *sf_dev; 161 164 u16 max_functions; 162 165 u16 sf_index; 163 166 u16 base_id; 164 167 165 - max_functions = mlx5_sf_max_functions(table->dev); 168 + if (!table) 169 + return 0; 170 + 171 + max_functions = mlx5_sf_max_functions(dev); 166 172 if (!max_functions) 167 173 return 0; 168 174 169 - base_id = mlx5_sf_start_function_id(table->dev); 175 + base_id = mlx5_sf_start_function_id(dev); 170 176 if (event->function_id < base_id || event->function_id >= (base_id + max_functions)) 171 177 return 0; 172 178 ··· 181 177 case MLX5_VHCA_STATE_INVALID: 182 178 case MLX5_VHCA_STATE_ALLOCATED: 183 179 if (sf_dev) 184 - mlx5_sf_dev_del(table->dev, sf_dev, sf_index); 180 + mlx5_sf_dev_del(dev, sf_dev, sf_index); 185 181 break; 186 182 case MLX5_VHCA_STATE_TEARDOWN_REQUEST: 187 183 if (sf_dev) 188 - mlx5_sf_dev_del(table->dev, sf_dev, sf_index); 184 + mlx5_sf_dev_del(dev, sf_dev, sf_index); 189 185 else 190 - mlx5_core_err(table->dev, 186 + mlx5_core_err(dev, 191 187 "SF DEV: teardown state for invalid dev index=%d sfnum=0x%x\n", 192 188 sf_index, event->sw_function_id); 193 189 break; 194 190 case MLX5_VHCA_STATE_ACTIVE: 195 191 if (!sf_dev) 196 - mlx5_sf_dev_add(table->dev, sf_index, event->function_id, 192 + mlx5_sf_dev_add(dev, sf_index, event->function_id, 197 193 event->sw_function_id); 198 194 break; 199 195 default: ··· 319 315 } 320 316 } 321 317 318 + int mlx5_sf_dev_notifier_init(struct mlx5_core_dev *dev) 319 + { 320 + if (mlx5_core_is_sf(dev)) 321 + return 0; 322 + 323 + dev->priv.sf_dev_nb.notifier_call = mlx5_sf_dev_state_change_handler; 324 + return mlx5_vhca_event_notifier_register(dev, &dev->priv.sf_dev_nb); 325 + } 326 + 322 327 void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) 323 328 { 324 329 struct mlx5_sf_dev_table *table; ··· 342 329 goto table_err; 343 330 } 344 331 345 - table->nb.notifier_call = mlx5_sf_dev_state_change_handler; 346 332 table->dev = dev; 347 333 table->sf_bar_length = 1 << (MLX5_CAP_GEN(dev, log_min_sf_size) + 12); 348 334 table->base_address = pci_resource_start(dev->pdev, 2); 349 335 xa_init(&table->devices); 350 336 dev->priv.sf_dev_table = table; 351 - 352 - err = mlx5_vhca_event_notifier_register(dev, &table->nb); 353 - if (err) 354 - goto vhca_err; 355 337 356 338 err = mlx5_sf_dev_create_active_works(table); 357 339 if (err) ··· 359 351 360 352 arm_err: 361 353 mlx5_sf_dev_destroy_active_works(table); 362 - add_active_err: 363 - mlx5_vhca_event_notifier_unregister(dev, &table->nb); 364 354 mlx5_vhca_event_work_queues_flush(dev); 365 - vhca_err: 355 + add_active_err: 366 356 kfree(table); 367 357 dev->priv.sf_dev_table = NULL; 368 358 table_err: ··· 378 372 } 379 373 } 380 374 375 + void mlx5_sf_dev_notifier_cleanup(struct mlx5_core_dev *dev) 376 + { 377 + if (mlx5_core_is_sf(dev)) 378 + return; 379 + 380 + mlx5_vhca_event_notifier_unregister(dev, &dev->priv.sf_dev_nb); 381 + } 382 + 381 383 void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev) 382 384 { 383 385 struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; ··· 394 380 return; 395 381 396 382 mlx5_sf_dev_destroy_active_works(table); 397 - mlx5_vhca_event_notifier_unregister(dev, &table->nb); 398 383 399 384 /* Now that event handler is not running, it is safe to destroy 400 385 * the sf device without race.
+11
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h
··· 25 25 int err; 26 26 }; 27 27 28 + int mlx5_sf_dev_notifier_init(struct mlx5_core_dev *dev); 28 29 void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev); 30 + void mlx5_sf_dev_notifier_cleanup(struct mlx5_core_dev *dev); 29 31 void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev); 30 32 31 33 int mlx5_sf_driver_register(void); ··· 37 35 38 36 #else 39 37 38 + static inline int mlx5_sf_dev_notifier_init(struct mlx5_core_dev *dev) 39 + { 40 + return 0; 41 + } 42 + 40 43 static inline void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) 44 + { 45 + } 46 + 47 + static inline void mlx5_sf_dev_notifier_cleanup(struct mlx5_core_dev *dev) 41 48 { 42 49 } 43 50
+1
include/linux/mlx5/driver.h
··· 616 616 #ifdef CONFIG_MLX5_SF 617 617 struct mlx5_nb vhca_state_nb; 618 618 struct blocking_notifier_head vhca_state_n_head; 619 + struct notifier_block sf_dev_nb; 619 620 struct mlx5_sf_dev_table *sf_dev_table; 620 621 struct mlx5_core_dev *parent_mdev; 621 622 #endif