Skip to content

Commit a760e80

Browse files
metze-sambasmfrench
authored andcommitted
RDMA/core: introduce rdma_restrict_node_type()
For smbdirect it required to use different ports depending on the RDMA protocol. E.g. for iWarp 5445 is needed (as tcp port 445 already used by the raw tcp transport for SMB), while InfiniBand, RoCEv1 and RoCEv2 use port 445, as they use an independent port range (even for RoCEv2, which uses udp port 4791 itself). Currently ksmbd is not able to function correctly at all if the system has iWarp (RDMA_NODE_RNIC) interface(s) and any InfiniBand, RoCEv1 and/or RoCEv2 interface(s) at the same time. And cifs.ko uses 5445 with a fallback to 445, which means depending on the available interfaces, it tries 5445 in the RoCE range or may tries iWarp with 445 as a fallback. This leads to strange error messages and strange network captures. To avoid these problems they will be able to use rdma_restrict_node_type(RDMA_NODE_RNIC) before trying port 5445 and rdma_restrict_node_type(RDMA_NODE_IB_CA) before trying port 445. It means we'll get early -ENODEV early from rdma_resolve_addr() without any network traffic and timeouts. This is designed to be called before calling any of rdma_bind_addr(), rdma_resolve_addr() or rdma_listen(). Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Steve French <smfrench@gmail.com> Cc: Tom Talpey <tom@talpey.com> Cc: Long Li <longli@microsoft.com> Cc: linux-rdma@vger.kernel.org Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Acked-by: Leon Romanovsky <leon@kernel.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent cf74fcd commit a760e80

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

drivers/infiniband/core/cma.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,9 @@ static int cma_acquire_dev_by_src_ip(struct rdma_id_private *id_priv)
793793

794794
mutex_lock(&lock);
795795
list_for_each_entry(cma_dev, &dev_list, list) {
796+
if (id_priv->restricted_node_type != RDMA_NODE_UNSPECIFIED &&
797+
id_priv->restricted_node_type != cma_dev->device->node_type)
798+
continue;
796799
rdma_for_each_port (cma_dev->device, port) {
797800
gidp = rdma_protocol_roce(cma_dev->device, port) ?
798801
&iboe_gid : &gid;
@@ -1015,6 +1018,7 @@ __rdma_create_id(struct net *net, rdma_cm_event_handler event_handler,
10151018
return ERR_PTR(-ENOMEM);
10161019

10171020
id_priv->state = RDMA_CM_IDLE;
1021+
id_priv->restricted_node_type = RDMA_NODE_UNSPECIFIED;
10181022
id_priv->id.context = context;
10191023
id_priv->id.event_handler = event_handler;
10201024
id_priv->id.ps = ps;
@@ -4177,6 +4181,32 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
41774181
}
41784182
EXPORT_SYMBOL(rdma_resolve_addr);
41794183

4184+
int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type)
4185+
{
4186+
struct rdma_id_private *id_priv =
4187+
container_of(id, struct rdma_id_private, id);
4188+
int ret = 0;
4189+
4190+
switch (node_type) {
4191+
case RDMA_NODE_UNSPECIFIED:
4192+
case RDMA_NODE_IB_CA:
4193+
case RDMA_NODE_RNIC:
4194+
break;
4195+
default:
4196+
return -EINVAL;
4197+
}
4198+
4199+
mutex_lock(&lock);
4200+
if (id_priv->cma_dev)
4201+
ret = -EALREADY;
4202+
else
4203+
id_priv->restricted_node_type = node_type;
4204+
mutex_unlock(&lock);
4205+
4206+
return ret;
4207+
}
4208+
EXPORT_SYMBOL(rdma_restrict_node_type);
4209+
41804210
int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
41814211
{
41824212
struct rdma_id_private *id_priv =

drivers/infiniband/core/cma_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct rdma_id_private {
7272

7373
int internal_id;
7474
enum rdma_cm_state state;
75+
u8 restricted_node_type;
7576
spinlock_t lock;
7677
struct mutex qp_mutex;
7778

include/rdma/rdma_cm.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,23 @@ struct rdma_cm_id *rdma_create_user_id(rdma_cm_event_handler event_handler,
168168
*/
169169
void rdma_destroy_id(struct rdma_cm_id *id);
170170

171+
/**
172+
* rdma_restrict_node_type - Restrict an RDMA identifier to specific
173+
* RDMA device node type.
174+
*
175+
* @id: RDMA identifier.
176+
* @node_type: The device node type. Only RDMA_NODE_UNSPECIFIED (default),
177+
* RDMA_NODE_RNIC and RDMA_NODE_IB_CA are allowed
178+
*
179+
* This allows the caller to restrict the possible devices
180+
* used to iWarp (RDMA_NODE_RNIC) or InfiniBand/RoCEv1/RoCEv2 (RDMA_NODE_IB_CA).
181+
*
182+
* It needs to be called before the RDMA identifier is bound
183+
* to an device, which mean it should be called before
184+
* rdma_bind_addr(), rdma_bind_addr() and rdma_listen().
185+
*/
186+
int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type);
187+
171188
/**
172189
* rdma_bind_addr - Bind an RDMA identifier to a source address and
173190
* associated RDMA device, if needed.

0 commit comments

Comments
 (0)