diff options
| -rw-r--r-- | drivers/infiniband/core/cma.c | 30 | ||||
| -rw-r--r-- | drivers/infiniband/core/cma_priv.h | 1 | ||||
| -rw-r--r-- | include/rdma/rdma_cm.h | 17 |
3 files changed, 48 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index f00f1d3fbd9c..0ee855a71ed4 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -793,6 +793,9 @@ static int cma_acquire_dev_by_src_ip(struct rdma_id_private *id_priv) mutex_lock(&lock); list_for_each_entry(cma_dev, &dev_list, list) { + if (id_priv->restricted_node_type != RDMA_NODE_UNSPECIFIED && + id_priv->restricted_node_type != cma_dev->device->node_type) + continue; rdma_for_each_port (cma_dev->device, port) { gidp = rdma_protocol_roce(cma_dev->device, port) ? &iboe_gid : &gid; @@ -1015,6 +1018,7 @@ __rdma_create_id(struct net *net, rdma_cm_event_handler event_handler, return ERR_PTR(-ENOMEM); id_priv->state = RDMA_CM_IDLE; + id_priv->restricted_node_type = RDMA_NODE_UNSPECIFIED; id_priv->id.context = context; id_priv->id.event_handler = event_handler; id_priv->id.ps = ps; @@ -4177,6 +4181,32 @@ err: } EXPORT_SYMBOL(rdma_resolve_addr); +int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type) +{ + struct rdma_id_private *id_priv = + container_of(id, struct rdma_id_private, id); + int ret = 0; + + switch (node_type) { + case RDMA_NODE_UNSPECIFIED: + case RDMA_NODE_IB_CA: + case RDMA_NODE_RNIC: + break; + default: + return -EINVAL; + } + + mutex_lock(&lock); + if (id_priv->cma_dev) + ret = -EALREADY; + else + id_priv->restricted_node_type = node_type; + mutex_unlock(&lock); + + return ret; +} +EXPORT_SYMBOL(rdma_restrict_node_type); + int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) { struct rdma_id_private *id_priv = diff --git a/drivers/infiniband/core/cma_priv.h b/drivers/infiniband/core/cma_priv.h index c604b601f4d9..04332eb82668 100644 --- a/drivers/infiniband/core/cma_priv.h +++ b/drivers/infiniband/core/cma_priv.h @@ -72,6 +72,7 @@ struct rdma_id_private { int internal_id; enum rdma_cm_state state; + u8 restricted_node_type; spinlock_t lock; struct mutex qp_mutex; diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index 9bd930a83e6e..6de6fd8bd15e 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h @@ -169,6 +169,23 @@ struct rdma_cm_id *rdma_create_user_id(rdma_cm_event_handler event_handler, void rdma_destroy_id(struct rdma_cm_id *id); /** + * rdma_restrict_node_type - Restrict an RDMA identifier to specific + * RDMA device node type. + * + * @id: RDMA identifier. + * @node_type: The device node type. Only RDMA_NODE_UNSPECIFIED (default), + * RDMA_NODE_RNIC and RDMA_NODE_IB_CA are allowed + * + * This allows the caller to restrict the possible devices + * used to iWarp (RDMA_NODE_RNIC) or InfiniBand/RoCEv1/RoCEv2 (RDMA_NODE_IB_CA). + * + * It needs to be called before the RDMA identifier is bound + * to an device, which mean it should be called before + * rdma_bind_addr(), rdma_bind_addr() and rdma_listen(). + */ +int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type); + +/** * rdma_bind_addr - Bind an RDMA identifier to a source address and * associated RDMA device, if needed. * |
