Skip to content

Commit 1c5de09

Browse files
author
Saeed Mahameed
committed
net/mlx5: Fix mlx5_get_next_dev() peer device matching
In some use-cases, mlx5 instances will need to search for their peer device (the other port on the same HCA). For that, mlx5 device matching mechanism relied on auxiliary_find_device() to search, and used a bad matching callback function. This approach has two issues: 1) next_phys_dev() the matching function, assumed all devices are of the type mlx5_adev (mlx5 auxiliary device) which is wrong and could lead to crashes, this worked for a while, since only lately other drivers started registering auxiliary devices. 2) using the auxiliary class bus (auxiliary_find_device) to search for mlx5_core_dev devices, who are actually PCIe device instances, is wrong. This works since mlx5_core always has at least one mlx5_adev instance hanging around in the aux bus. As suggested by others we can fix 1. by comparing device names prefixes if they have the string "mlx5_core" in them, which is not a best practice ! but even with that fixed, still 2. needs fixing, we are trying to match pcie device peers so we should look in the right bus (pci bus), hence this fix. The fix: 1) search the pci bus for mlx5 peer devices, instead of the aux bus 2) to validated devices are the same type "mlx5_core_dev" compare if they have the same driver, which is bulletproof. This wouldn't have worked with the aux bus since the various mlx5 aux device types don't share the same driver, even if they share the same device wrapper struct (mlx5_adev) "which helped to find the parent device" Fixes: a925b5e ("net/mlx5: Register mlx5 devices to auxiliary virtual bus") Reported-by: Alexander Lobakin <[email protected]> Reported-by: Maher Sanalla <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Reviewed-by: Mark Bloch <[email protected]> Reviewed-by: Maher Sanalla <[email protected]>
1 parent f6279f1 commit 1c5de09

File tree

1 file changed

+23
-11
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+23
-11
lines changed

drivers/net/ethernet/mellanox/mlx5/core/dev.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -571,18 +571,32 @@ static int _next_phys_dev(struct mlx5_core_dev *mdev,
571571
return 1;
572572
}
573573

574+
static void *pci_get_other_drvdata(struct device *this, struct device *other)
575+
{
576+
if (this->driver != other->driver)
577+
return NULL;
578+
579+
return pci_get_drvdata(to_pci_dev(other));
580+
}
581+
574582
static int next_phys_dev(struct device *dev, const void *data)
575583
{
576-
struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev);
577-
struct mlx5_core_dev *mdev = madev->mdev;
584+
struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data;
585+
586+
mdev = pci_get_other_drvdata(this->device, dev);
587+
if (!mdev)
588+
return 0;
578589

579590
return _next_phys_dev(mdev, data);
580591
}
581592

582593
static int next_phys_dev_lag(struct device *dev, const void *data)
583594
{
584-
struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev);
585-
struct mlx5_core_dev *mdev = madev->mdev;
595+
struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data;
596+
597+
mdev = pci_get_other_drvdata(this->device, dev);
598+
if (!mdev)
599+
return 0;
586600

587601
if (!MLX5_CAP_GEN(mdev, vport_group_manager) ||
588602
!MLX5_CAP_GEN(mdev, lag_master) ||
@@ -596,19 +610,17 @@ static int next_phys_dev_lag(struct device *dev, const void *data)
596610
static struct mlx5_core_dev *mlx5_get_next_dev(struct mlx5_core_dev *dev,
597611
int (*match)(struct device *dev, const void *data))
598612
{
599-
struct auxiliary_device *adev;
600-
struct mlx5_adev *madev;
613+
struct device *next;
601614

602615
if (!mlx5_core_is_pf(dev))
603616
return NULL;
604617

605-
adev = auxiliary_find_device(NULL, dev, match);
606-
if (!adev)
618+
next = bus_find_device(&pci_bus_type, NULL, dev, match);
619+
if (!next)
607620
return NULL;
608621

609-
madev = container_of(adev, struct mlx5_adev, adev);
610-
put_device(&adev->dev);
611-
return madev->mdev;
622+
put_device(next);
623+
return pci_get_drvdata(to_pci_dev(next));
612624
}
613625

614626
/* Must be called with intf_mutex held */

0 commit comments

Comments
 (0)