]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/mlx5: Devcom, serialize devcom registration
authorShay Drory <shayd@nvidia.com>
Tue, 2 May 2023 10:36:42 +0000 (13:36 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 May 2023 13:03:33 +0000 (14:03 +0100)
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: 38d7b8849540 ("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>
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c

index 8f978491dd32f56eba68d881716db062d49d515e..b7d779d08d8371082415d439b547e54cf6f6b8e5 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/mlx5/vport.h>
 #include "lib/devcom.h"
+#include "mlx5_core.h"
 
 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)
                return NULL;
 
+       mlx5_dev_list_lock();
        sguid0 = mlx5_query_nic_system_image_guid(dev);
        list_for_each_entry(iter, &devcom_list, list) {
                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) {
                priv = mlx5_devcom_list_alloc();
-               if (!priv)
-                       return ERR_PTR(-ENOMEM);
+               if (!priv) {
+                       devcom = ERR_PTR(-ENOMEM);
+                       goto out;
+               }
 
                idx = 0;
                new_priv = true;
@@ -114,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
        if (!devcom) {
                if (new_priv)
                        kfree(priv);
-               return ERR_PTR(-ENOMEM);
+               devcom = ERR_PTR(-ENOMEM);
+               goto out;
        }
 
        if (new_priv)
                list_add(&priv->list, &devcom_list);
-
+out:
+       mlx5_dev_list_unlock();
        return devcom;
 }
 
@@ -132,6 +138,7 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
        if (IS_ERR_OR_NULL(devcom))
                return;
 
+       mlx5_dev_list_lock();
        priv = devcom->priv;
        priv->devs[devcom->idx] = NULL;
 
@@ -142,10 +149,12 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
                        break;
 
        if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
-               return;
+               goto out;
 
        list_del(&priv->list);
        kfree(priv);
+out:
+       mlx5_dev_list_unlock();
 }
 
 void mlx5_devcom_register_component(struct mlx5_devcom *devcom,