Commit 0d9ba6ae authored by Shay Drory's avatar Shay Drory Committed by sanglipeng
Browse files

net/mlx5: Devcom, serialize devcom registration

stable inclusion
from stable-v5.10.182
commit b556990235c33460a9d072b93f8dad3822ce4249
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8GJZJ

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b556990235c33460a9d072b93f8dad3822ce4249



--------------------------------

[ Upstream commit 1f893f57 ]

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: fadd59fc ("net/mlx5: Introduce inter-device communication mechanism")
Signed-off-by: default avatarShay Drory <shayd@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent c5b937bf
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -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,