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

Commit 832369fa authored by Brian Welty's avatar Brian Welty Committed by Doug Ledford
Browse files

IB/{hfi1, qib, rdmavt}: Move logic to allocate receive WQE into rdmavt



Moving receive-side WQE allocation logic into rdmavt will allow
further code reuse between qib and hfi1 drivers.

Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarBrian Welty <brian.welty@intel.com>
Signed-off-by: default avatarHarish Chegondi <harish.chegondi@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 5d18ee67
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -2123,7 +2123,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
	/* OK, process the packet. */
	/* OK, process the packet. */
	switch (opcode) {
	switch (opcode) {
	case OP(SEND_FIRST):
	case OP(SEND_FIRST):
		ret = hfi1_rvt_get_rwqe(qp, 0);
		ret = rvt_get_rwqe(qp, false);
		if (ret < 0)
		if (ret < 0)
			goto nack_op_err;
			goto nack_op_err;
		if (!ret)
		if (!ret)
@@ -2149,7 +2149,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)


	case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE):
	case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE):
		/* consume RWQE */
		/* consume RWQE */
		ret = hfi1_rvt_get_rwqe(qp, 1);
		ret = rvt_get_rwqe(qp, true);
		if (ret < 0)
		if (ret < 0)
			goto nack_op_err;
			goto nack_op_err;
		if (!ret)
		if (!ret)
@@ -2159,7 +2159,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
	case OP(SEND_ONLY):
	case OP(SEND_ONLY):
	case OP(SEND_ONLY_WITH_IMMEDIATE):
	case OP(SEND_ONLY_WITH_IMMEDIATE):
	case OP(SEND_ONLY_WITH_INVALIDATE):
	case OP(SEND_ONLY_WITH_INVALIDATE):
		ret = hfi1_rvt_get_rwqe(qp, 0);
		ret = rvt_get_rwqe(qp, false);
		if (ret < 0)
		if (ret < 0)
			goto nack_op_err;
			goto nack_op_err;
		if (!ret)
		if (!ret)
@@ -2271,7 +2271,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
			goto send_middle;
			goto send_middle;
		else if (opcode == OP(RDMA_WRITE_ONLY))
		else if (opcode == OP(RDMA_WRITE_ONLY))
			goto no_immediate_data;
			goto no_immediate_data;
		ret = hfi1_rvt_get_rwqe(qp, 1);
		ret = rvt_get_rwqe(qp, true);
		if (ret < 0)
		if (ret < 0)
			goto nack_op_err;
			goto nack_op_err;
		if (!ret) {
		if (!ret) {
+2 −152
Original line number Original line Diff line number Diff line
@@ -53,156 +53,6 @@
#include "verbs_txreq.h"
#include "verbs_txreq.h"
#include "trace.h"
#include "trace.h"


/*
 * Validate a RWQE and fill in the SGE state.
 * Return 1 if OK.
 */
static int init_sge(struct rvt_qp *qp, struct rvt_rwqe *wqe)
{
	int i, j, ret;
	struct ib_wc wc;
	struct rvt_lkey_table *rkt;
	struct rvt_pd *pd;
	struct rvt_sge_state *ss;

	rkt = &to_idev(qp->ibqp.device)->rdi.lkey_table;
	pd = ibpd_to_rvtpd(qp->ibqp.srq ? qp->ibqp.srq->pd : qp->ibqp.pd);
	ss = &qp->r_sge;
	ss->sg_list = qp->r_sg_list;
	qp->r_len = 0;
	for (i = j = 0; i < wqe->num_sge; i++) {
		if (wqe->sg_list[i].length == 0)
			continue;
		/* Check LKEY */
		ret = rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
				  NULL, &wqe->sg_list[i],
				  IB_ACCESS_LOCAL_WRITE);
		if (unlikely(ret <= 0))
			goto bad_lkey;
		qp->r_len += wqe->sg_list[i].length;
		j++;
	}
	ss->num_sge = j;
	ss->total_len = qp->r_len;
	ret = 1;
	goto bail;

bad_lkey:
	while (j) {
		struct rvt_sge *sge = --j ? &ss->sg_list[j - 1] : &ss->sge;

		rvt_put_mr(sge->mr);
	}
	ss->num_sge = 0;
	memset(&wc, 0, sizeof(wc));
	wc.wr_id = wqe->wr_id;
	wc.status = IB_WC_LOC_PROT_ERR;
	wc.opcode = IB_WC_RECV;
	wc.qp = &qp->ibqp;
	/* Signal solicited completion event. */
	rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc, 1);
	ret = 0;
bail:
	return ret;
}

/**
 * hfi1_rvt_get_rwqe - copy the next RWQE into the QP's RWQE
 * @qp: the QP
 * @wr_id_only: update qp->r_wr_id only, not qp->r_sge
 *
 * Return -1 if there is a local error, 0 if no RWQE is available,
 * otherwise return 1.
 *
 * Can be called from interrupt level.
 */
int hfi1_rvt_get_rwqe(struct rvt_qp *qp, int wr_id_only)
{
	unsigned long flags;
	struct rvt_rq *rq;
	struct rvt_rwq *wq;
	struct rvt_srq *srq;
	struct rvt_rwqe *wqe;
	void (*handler)(struct ib_event *, void *);
	u32 tail;
	int ret;

	if (qp->ibqp.srq) {
		srq = ibsrq_to_rvtsrq(qp->ibqp.srq);
		handler = srq->ibsrq.event_handler;
		rq = &srq->rq;
	} else {
		srq = NULL;
		handler = NULL;
		rq = &qp->r_rq;
	}

	spin_lock_irqsave(&rq->lock, flags);
	if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) {
		ret = 0;
		goto unlock;
	}

	wq = rq->wq;
	tail = wq->tail;
	/* Validate tail before using it since it is user writable. */
	if (tail >= rq->size)
		tail = 0;
	if (unlikely(tail == wq->head)) {
		ret = 0;
		goto unlock;
	}
	/* Make sure entry is read after head index is read. */
	smp_rmb();
	wqe = rvt_get_rwqe_ptr(rq, tail);
	/*
	 * Even though we update the tail index in memory, the verbs
	 * consumer is not supposed to post more entries until a
	 * completion is generated.
	 */
	if (++tail >= rq->size)
		tail = 0;
	wq->tail = tail;
	if (!wr_id_only && !init_sge(qp, wqe)) {
		ret = -1;
		goto unlock;
	}
	qp->r_wr_id = wqe->wr_id;

	ret = 1;
	set_bit(RVT_R_WRID_VALID, &qp->r_aflags);
	if (handler) {
		u32 n;

		/*
		 * Validate head pointer value and compute
		 * the number of remaining WQEs.
		 */
		n = wq->head;
		if (n >= rq->size)
			n = 0;
		if (n < tail)
			n += rq->size - tail;
		else
			n -= tail;
		if (n < srq->limit) {
			struct ib_event ev;

			srq->limit = 0;
			spin_unlock_irqrestore(&rq->lock, flags);
			ev.device = qp->ibqp.device;
			ev.element.srq = qp->ibqp.srq;
			ev.event = IB_EVENT_SRQ_LIMIT_REACHED;
			handler(&ev, srq->ibsrq.srq_context);
			goto bail;
		}
	}
unlock:
	spin_unlock_irqrestore(&rq->lock, flags);
bail:
	return ret;
}

static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
{
{
	return (gid->global.interface_id == id &&
	return (gid->global.interface_id == id &&
@@ -423,7 +273,7 @@ static void ruc_loopback(struct rvt_qp *sqp)
		/* FALLTHROUGH */
		/* FALLTHROUGH */
	case IB_WR_SEND:
	case IB_WR_SEND:
send:
send:
		ret = hfi1_rvt_get_rwqe(qp, 0);
		ret = rvt_get_rwqe(qp, false);
		if (ret < 0)
		if (ret < 0)
			goto op_err;
			goto op_err;
		if (!ret)
		if (!ret)
@@ -435,7 +285,7 @@ static void ruc_loopback(struct rvt_qp *sqp)
			goto inv_err;
			goto inv_err;
		wc.wc_flags = IB_WC_WITH_IMM;
		wc.wc_flags = IB_WC_WITH_IMM;
		wc.ex.imm_data = wqe->wr.ex.imm_data;
		wc.ex.imm_data = wqe->wr.ex.imm_data;
		ret = hfi1_rvt_get_rwqe(qp, 1);
		ret = rvt_get_rwqe(qp, true);
		if (ret < 0)
		if (ret < 0)
			goto op_err;
			goto op_err;
		if (!ret)
		if (!ret)
+2 −2
Original line number Original line Diff line number Diff line
@@ -397,7 +397,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet)
		if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) {
		if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) {
			qp->r_sge = qp->s_rdma_read_sge;
			qp->r_sge = qp->s_rdma_read_sge;
		} else {
		} else {
			ret = hfi1_rvt_get_rwqe(qp, 0);
			ret = rvt_get_rwqe(qp, false);
			if (ret < 0)
			if (ret < 0)
				goto op_err;
				goto op_err;
			if (!ret)
			if (!ret)
@@ -542,7 +542,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet)
		if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) {
		if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) {
			rvt_put_ss(&qp->s_rdma_read_sge);
			rvt_put_ss(&qp->s_rdma_read_sge);
		} else {
		} else {
			ret = hfi1_rvt_get_rwqe(qp, 1);
			ret = rvt_get_rwqe(qp, true);
			if (ret < 0)
			if (ret < 0)
				goto op_err;
				goto op_err;
			if (!ret)
			if (!ret)
+2 −2
Original line number Original line Diff line number Diff line
@@ -163,7 +163,7 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
	} else {
	} else {
		int ret;
		int ret;


		ret = hfi1_rvt_get_rwqe(qp, 0);
		ret = rvt_get_rwqe(qp, false);
		if (ret < 0) {
		if (ret < 0) {
			rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
			rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
			goto bail_unlock;
			goto bail_unlock;
@@ -974,7 +974,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
	} else {
	} else {
		int ret;
		int ret;


		ret = hfi1_rvt_get_rwqe(qp, 0);
		ret = rvt_get_rwqe(qp, false);
		if (ret < 0) {
		if (ret < 0) {
			rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
			rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
			return;
			return;
+0 −2
Original line number Original line Diff line number Diff line
@@ -328,8 +328,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet);


int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey);
int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey);


int hfi1_rvt_get_rwqe(struct rvt_qp *qp, int wr_id_only);

void hfi1_migrate_qp(struct rvt_qp *qp);
void hfi1_migrate_qp(struct rvt_qp *qp);


int hfi1_check_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
int hfi1_check_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,
Loading