net/mlx5: Devcom, serialize devcom registration
commit 1f893f57a3bf9fe1f4bcb25b55aea7f7f9712fe7 upstream.
From one hand, mlx5 driver is allowing to probe PFs in parallel.
From the other hand, devcom, which is a share resource between PFs, is
registered without any lock. This might resulted in memory problems.
Hence, use the global mlx5_dev_list_lock in order to serialize devcom
registration.
Fixes: fadd59fc50
("net/mlx5: Introduce inter-device communication mechanism")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
eaa365c104
commit
3e8a82fb55
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <linux/mlx5/vport.h>
|
#include <linux/mlx5/vport.h>
|
||||||
#include "lib/devcom.h"
|
#include "lib/devcom.h"
|
||||||
|
#include "mlx5_core.h"
|
||||||
|
|
||||||
static LIST_HEAD(devcom_list);
|
static LIST_HEAD(devcom_list);
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
|
if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
mlx5_dev_list_lock();
|
||||||
sguid0 = mlx5_query_nic_system_image_guid(dev);
|
sguid0 = mlx5_query_nic_system_image_guid(dev);
|
||||||
list_for_each_entry(iter, &devcom_list, list) {
|
list_for_each_entry(iter, &devcom_list, list) {
|
||||||
struct mlx5_core_dev *tmp_dev = NULL;
|
struct mlx5_core_dev *tmp_dev = NULL;
|
||||||
@ -102,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
|
|
||||||
if (!priv) {
|
if (!priv) {
|
||||||
priv = mlx5_devcom_list_alloc();
|
priv = mlx5_devcom_list_alloc();
|
||||||
if (!priv)
|
if (!priv) {
|
||||||
return ERR_PTR(-ENOMEM);
|
devcom = ERR_PTR(-ENOMEM);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
new_priv = true;
|
new_priv = true;
|
||||||
@ -114,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
|||||||
if (!devcom) {
|
if (!devcom) {
|
||||||
if (new_priv)
|
if (new_priv)
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
return ERR_PTR(-ENOMEM);
|
devcom = ERR_PTR(-ENOMEM);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_priv)
|
if (new_priv)
|
||||||
list_add(&priv->list, &devcom_list);
|
list_add(&priv->list, &devcom_list);
|
||||||
|
out:
|
||||||
|
mlx5_dev_list_unlock();
|
||||||
return devcom;
|
return devcom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +138,7 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
|
|||||||
if (IS_ERR_OR_NULL(devcom))
|
if (IS_ERR_OR_NULL(devcom))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mlx5_dev_list_lock();
|
||||||
priv = devcom->priv;
|
priv = devcom->priv;
|
||||||
priv->devs[devcom->idx] = NULL;
|
priv->devs[devcom->idx] = NULL;
|
||||||
|
|
||||||
@ -142,10 +149,12 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
|
if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
list_del(&priv->list);
|
list_del(&priv->list);
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
|
out:
|
||||||
|
mlx5_dev_list_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
||||||
|
Loading…
Reference in New Issue
Block a user