diff mbox series

[3/3] RDMA/core: Get all the ib devices from net devices

Message ID 20221023220450.2287909-4-yanjun.zhu@intel.com (mailing list archive)
State Changes Requested
Delegated to: Jason Gunthorpe
Headers show
Series RDMA net namespace | expand

Commit Message

Zhu Yanjun Oct. 23, 2022, 10:04 p.m. UTC
From: Zhu Yanjun <yanjun.zhu@linux.dev>

To mlx4/5, the function ib_device_get_by_netdev can not get
ib devices from net devices.

So this function parses all the ib devices to get all the net
devices, then compares the net devices with the given net device.

Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
---
 drivers/infiniband/core/device.c | 39 ++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d38eb1fc2ed7..55e2d75d752e 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -2740,14 +2740,49 @@  int ib_dma_virt_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents)
 EXPORT_SYMBOL(ib_dma_virt_map_sg);
 #endif /* CONFIG_INFINIBAND_VIRT_DMA */
 
+static struct ib_device *get_ibdev_from_ndev(struct net_device *ndev)
+{
+	unsigned long index;
+	struct ib_device *dev;
+	int i;
+
+	down_read(&devices_rwsem);
+	xa_for_each_marked(&devices, index, dev, DEVICE_REGISTERED) {
+		if (!dev->ops.get_netdev)
+			continue;
+
+		for (i = 0; i < dev->phys_port_cnt; i++) {
+			struct net_device *netdev;
+
+			netdev = dev->ops.get_netdev(dev, i+1);
+			if (!netdev)
+				continue;
+
+			dev_put(netdev);
+			if (ndev == netdev) {
+				up_read(&devices_rwsem);
+				if (!ib_device_try_get(dev))
+					dev = NULL;
+				return dev;
+			}
+		}
+	}
+	up_read(&devices_rwsem);
+	return NULL;
+}
+
 static int rdma_netns_notify(struct notifier_block *not_blk,
 			     unsigned long event, void *arg)
 {
 	struct net_device *ndev = netdev_notifier_info_to_dev(arg);
 	struct ib_device *ibdev = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
 
-	if (!ibdev)
-		return NOTIFY_OK;
+	if (!ibdev) {
+		/* This is for MLX4/5 */
+		ibdev = get_ibdev_from_ndev(ndev);
+		if (!ibdev)
+			return NOTIFY_OK;
+	}
 
 	/* This will exclude IB device */
 	if (rdma_protocol_ib(ibdev, rdma_start_port(ibdev))) {