diff options
Diffstat (limited to 'drivers/infiniband/core')
| -rw-r--r-- | drivers/infiniband/core/cma.c | 48 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_std_types_device.c | 3 | 
2 files changed, 38 insertions, 13 deletions
| diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 7c2ab1f2fbea..a77750b8954d 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -405,10 +405,10 @@ static int cma_comp_exch(struct rdma_id_private *id_priv,  	/*  	 * The FSM uses a funny double locking where state is protected by both  	 * the handler_mutex and the spinlock. State is not allowed to change -	 * away from a handler_mutex protected value without also holding +	 * to/from a handler_mutex protected value without also holding  	 * handler_mutex.  	 */ -	if (comp == RDMA_CM_CONNECT) +	if (comp == RDMA_CM_CONNECT || exch == RDMA_CM_CONNECT)  		lockdep_assert_held(&id_priv->handler_mutex);  	spin_lock_irqsave(&id_priv->lock, flags); @@ -4038,17 +4038,23 @@ out:  	return ret;  } -int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) +/** + * rdma_connect_locked - Initiate an active connection request. + * @id: Connection identifier to connect. + * @conn_param: Connection information used for connected QPs. + * + * Same as rdma_connect() but can only be called from the + * RDMA_CM_EVENT_ROUTE_RESOLVED handler callback. + */ +int rdma_connect_locked(struct rdma_cm_id *id, +			struct rdma_conn_param *conn_param)  {  	struct rdma_id_private *id_priv =  		container_of(id, struct rdma_id_private, id);  	int ret; -	mutex_lock(&id_priv->handler_mutex); -	if (!cma_comp_exch(id_priv, RDMA_CM_ROUTE_RESOLVED, RDMA_CM_CONNECT)) { -		ret = -EINVAL; -		goto err_unlock; -	} +	if (!cma_comp_exch(id_priv, RDMA_CM_ROUTE_RESOLVED, RDMA_CM_CONNECT)) +		return -EINVAL;  	if (!id->qp) {  		id_priv->qp_num = conn_param->qp_num; @@ -4066,11 +4072,33 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)  		ret = -ENOSYS;  	if (ret)  		goto err_state; -	mutex_unlock(&id_priv->handler_mutex);  	return 0;  err_state:  	cma_comp_exch(id_priv, RDMA_CM_CONNECT, RDMA_CM_ROUTE_RESOLVED); -err_unlock: +	return ret; +} +EXPORT_SYMBOL(rdma_connect_locked); + +/** + * rdma_connect - Initiate an active connection request. + * @id: Connection identifier to connect. + * @conn_param: Connection information used for connected QPs. + * + * Users must have resolved a route for the rdma_cm_id to connect with by having + * called rdma_resolve_route before calling this routine. + * + * This call will either connect to a remote QP or obtain remote QP information + * for unconnected rdma_cm_id's.  The actual operation is based on the + * rdma_cm_id's port space. + */ +int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) +{ +	struct rdma_id_private *id_priv = +		container_of(id, struct rdma_id_private, id); +	int ret; + +	mutex_lock(&id_priv->handler_mutex); +	ret = rdma_connect_locked(id, conn_param);  	mutex_unlock(&id_priv->handler_mutex);  	return ret;  } diff --git a/drivers/infiniband/core/uverbs_std_types_device.c b/drivers/infiniband/core/uverbs_std_types_device.c index f367d523a46b..302f898c5833 100644 --- a/drivers/infiniband/core/uverbs_std_types_device.c +++ b/drivers/infiniband/core/uverbs_std_types_device.c @@ -401,9 +401,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_GID_ENTRY)(  	if (!rdma_is_port_valid(ib_dev, port_num))  		return -EINVAL; -	if (!rdma_ib_or_roce(ib_dev, port_num)) -		return -EOPNOTSUPP; -  	gid_attr = rdma_get_gid_attr(ib_dev, port_num, gid_index);  	if (IS_ERR(gid_attr))  		return PTR_ERR(gid_attr); |