Skip to content

Commit ecce70c

Browse files
chaserhkjsmfrench
authored andcommitted
ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()
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 <[email protected]> Acked-by: Namjae Jeon <[email protected]> Reviewed-by: Tom Talpey <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 807252f commit ecce70c

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

fs/smb/server/transport_rdma.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,8 +2140,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev)
21402140
if (ib_dev->node_type != RDMA_NODE_IB_CA)
21412141
smb_direct_port = SMB_DIRECT_PORT_IWARP;
21422142

2143-
if (!ib_dev->ops.get_netdev ||
2144-
!rdma_frwr_is_supported(&ib_dev->attrs))
2143+
if (!rdma_frwr_is_supported(&ib_dev->attrs))
21452144
return 0;
21462145

21472146
smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL);
@@ -2241,17 +2240,38 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev)
22412240
for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) {
22422241
struct net_device *ndev;
22432242

2244-
ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev,
2245-
i + 1);
2246-
if (!ndev)
2247-
continue;
2243+
if (smb_dev->ib_dev->ops.get_netdev) {
2244+
ndev = smb_dev->ib_dev->ops.get_netdev(
2245+
smb_dev->ib_dev, i + 1);
2246+
if (!ndev)
2247+
continue;
22482248

2249-
if (ndev == netdev) {
2249+
if (ndev == netdev) {
2250+
dev_put(ndev);
2251+
rdma_capable = true;
2252+
goto out;
2253+
}
22502254
dev_put(ndev);
2251-
rdma_capable = true;
2252-
goto out;
2255+
/* if ib_dev does not implement ops.get_netdev
2256+
* check for matching infiniband GUID in hw_addr
2257+
*/
2258+
} else if (netdev->type == ARPHRD_INFINIBAND) {
2259+
struct netdev_hw_addr *ha;
2260+
union ib_gid gid;
2261+
u32 port_num;
2262+
int ret;
2263+
2264+
netdev_hw_addr_list_for_each(
2265+
ha, &netdev->dev_addrs) {
2266+
memcpy(&gid, ha->addr + 4, sizeof(gid));
2267+
ret = ib_find_gid(smb_dev->ib_dev, &gid,
2268+
&port_num, NULL);
2269+
if (!ret) {
2270+
rdma_capable = true;
2271+
goto out;
2272+
}
2273+
}
22532274
}
2254-
dev_put(ndev);
22552275
}
22562276
}
22572277
out:

0 commit comments

Comments
 (0)