Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9977f4f6 authored by Sean Hefty's avatar Sean Hefty Committed by Roland Dreier
Browse files

RDMA/uverbs: Export XRC INI QPs to userspace



XRC INI QPs are similar to send only RC QPs.  Allow user space to create
INI QPs.  Note that INI QPs do not require receive CQs.

Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 8541f8de
Loading
Loading
Loading
Loading
+37 −11
Original line number Original line Diff line number Diff line
@@ -1371,8 +1371,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
	struct ib_udata                 udata;
	struct ib_udata                 udata;
	struct ib_uqp_object           *obj;
	struct ib_uqp_object           *obj;
	struct ib_pd                   *pd;
	struct ib_pd                   *pd;
	struct ib_cq                   *scq, *rcq;
	struct ib_cq                   *scq, *rcq = NULL;
	struct ib_srq                  *srq;
	struct ib_srq                  *srq = NULL;
	struct ib_qp                   *qp;
	struct ib_qp                   *qp;
	struct ib_qp_init_attr          attr;
	struct ib_qp_init_attr          attr;
	int ret;
	int ret;
@@ -1394,17 +1394,30 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
	init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key);
	init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key);
	down_write(&obj->uevent.uobject.mutex);
	down_write(&obj->uevent.uobject.mutex);


	srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
	pd  = idr_read_pd(cmd.pd_handle, file->ucontext);
	pd  = idr_read_pd(cmd.pd_handle, file->ucontext);
	scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0);
	scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0);
	rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
	if (!pd || !scq) {
		scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
		ret = -EINVAL;
		goto err_put;
	}


	if (!pd || !scq || !rcq ||
	if (cmd.qp_type == IB_QPT_XRC_INI) {
	    (cmd.is_srq && (!srq || srq->srq_type != IB_SRQT_BASIC))) {
		cmd.max_recv_wr = cmd.max_recv_sge = 0;
	} else {
		if (cmd.is_srq) {
			srq = idr_read_srq(cmd.srq_handle, file->ucontext);
			if (!srq || srq->srq_type != IB_SRQT_BASIC) {
				ret = -EINVAL;
				ret = -EINVAL;
				goto err_put;
				goto err_put;
			}
			}
		}
		rcq = (cmd.recv_cq_handle == cmd.send_cq_handle) ?
		       scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
		if (!rcq) {
			ret = -EINVAL;
			goto err_put;
		}
	}


	attr.event_handler = ib_uverbs_qp_event_handler;
	attr.event_handler = ib_uverbs_qp_event_handler;
	attr.qp_context    = file;
	attr.qp_context    = file;
@@ -1442,6 +1455,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
	qp->qp_type	  = attr.qp_type;
	qp->qp_type	  = attr.qp_type;
	atomic_inc(&pd->usecnt);
	atomic_inc(&pd->usecnt);
	atomic_inc(&attr.send_cq->usecnt);
	atomic_inc(&attr.send_cq->usecnt);
	if (attr.recv_cq)
		atomic_inc(&attr.recv_cq->usecnt);
		atomic_inc(&attr.recv_cq->usecnt);
	if (attr.srq)
	if (attr.srq)
		atomic_inc(&attr.srq->usecnt);
		atomic_inc(&attr.srq->usecnt);
@@ -1468,7 +1482,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,


	put_pd_read(pd);
	put_pd_read(pd);
	put_cq_read(scq);
	put_cq_read(scq);
	if (rcq != scq)
	if (rcq && rcq != scq)
		put_cq_read(rcq);
		put_cq_read(rcq);
	if (srq)
	if (srq)
		put_srq_read(srq);
		put_srq_read(srq);
@@ -1603,6 +1617,17 @@ out:
	return ret ? ret : in_len;
	return ret ? ret : in_len;
}
}


/* Remove ignored fields set in the attribute mask */
static int modify_qp_mask(enum ib_qp_type qp_type, int mask)
{
	switch (qp_type) {
	case IB_QPT_XRC_INI:
		return mask & ~(IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER);
	default:
		return mask;
	}
}

ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
			    const char __user *buf, int in_len,
			    const char __user *buf, int in_len,
			    int out_len)
			    int out_len)
@@ -1675,7 +1700,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
	attr->alt_ah_attr.ah_flags 	    = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
	attr->alt_ah_attr.ah_flags 	    = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
	attr->alt_ah_attr.port_num 	    = cmd.alt_dest.port_num;
	attr->alt_ah_attr.port_num 	    = cmd.alt_dest.port_num;


	ret = qp->device->modify_qp(qp, attr, cmd.attr_mask, &udata);
	ret = qp->device->modify_qp(qp, attr,
				    modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);


	put_qp_read(qp);
	put_qp_read(qp);