ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()
[ Upstream commit ecce70cf17d91c3dd87a0c4ea00b2d1387729701 ] Physical ib_device does not have an underlying net_device, thus its association with IPoIB net_device cannot be retrieved via ops.get_netdev() or ib_device_get_by_netdev(). ksmbd reads physical ib_device port GUID from the lower 16 bytes of the hardware addresses on IPoIB net_device and match its underlying ib_device using ib_find_gid() Signed-off-by: Kangjing Huang <huangkangjing@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Reviewed-by: Tom Talpey <tom@talpey.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
31c453b374
commit
dca63bad39
|
@ -2140,8 +2140,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev)
|
||||||
if (ib_dev->node_type != RDMA_NODE_IB_CA)
|
if (ib_dev->node_type != RDMA_NODE_IB_CA)
|
||||||
smb_direct_port = SMB_DIRECT_PORT_IWARP;
|
smb_direct_port = SMB_DIRECT_PORT_IWARP;
|
||||||
|
|
||||||
if (!ib_dev->ops.get_netdev ||
|
if (!rdma_frwr_is_supported(&ib_dev->attrs))
|
||||||
!rdma_frwr_is_supported(&ib_dev->attrs))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL);
|
smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL);
|
||||||
|
@ -2241,17 +2240,38 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev)
|
||||||
for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) {
|
for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) {
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
|
|
||||||
ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev,
|
if (smb_dev->ib_dev->ops.get_netdev) {
|
||||||
i + 1);
|
ndev = smb_dev->ib_dev->ops.get_netdev(
|
||||||
if (!ndev)
|
smb_dev->ib_dev, i + 1);
|
||||||
continue;
|
if (!ndev)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ndev == netdev) {
|
if (ndev == netdev) {
|
||||||
|
dev_put(ndev);
|
||||||
|
rdma_capable = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
dev_put(ndev);
|
dev_put(ndev);
|
||||||
rdma_capable = true;
|
/* if ib_dev does not implement ops.get_netdev
|
||||||
goto out;
|
* check for matching infiniband GUID in hw_addr
|
||||||
|
*/
|
||||||
|
} else if (netdev->type == ARPHRD_INFINIBAND) {
|
||||||
|
struct netdev_hw_addr *ha;
|
||||||
|
union ib_gid gid;
|
||||||
|
u32 port_num;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
netdev_hw_addr_list_for_each(
|
||||||
|
ha, &netdev->dev_addrs) {
|
||||||
|
memcpy(&gid, ha->addr + 4, sizeof(gid));
|
||||||
|
ret = ib_find_gid(smb_dev->ib_dev, &gid,
|
||||||
|
&port_num, NULL);
|
||||||
|
if (!ret) {
|
||||||
|
rdma_capable = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dev_put(ndev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue