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

Commit d42b01b5 authored by Ralph Campbell's avatar Ralph Campbell Committed by Roland Dreier
Browse files

IB/ipath: Implement IB_EVENT_QP_LAST_WQE_REACHED



This patch implements the IB_EVENT_QP_LAST_WQE_REACHED event which is
needed by ib_ipoib to destroy the QP when used in connected mode.

Signed-off-by: default avatarRalph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent c9cf7db2
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -377,13 +377,15 @@ static void ipath_reset_qp(struct ipath_qp *qp)
 * @err: the receive completion error to signal if a RWQE is active
 *
 * Flushes both send and receive work queues.
 * Returns true if last WQE event should be generated.
 * The QP s_lock should be held and interrupts disabled.
 */

void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
{
	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
	struct ib_wc wc;
	int ret = 0;

	ipath_dbg("QP%d/%d in error state\n",
		  qp->ibqp.qp_num, qp->remote_qpn);
@@ -454,7 +456,10 @@ void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
		wq->tail = tail;

		spin_unlock(&qp->r_rq.lock);
	}
	} else if (qp->ibqp.event_handler)
		ret = 1;

	return ret;
}

/**
@@ -473,6 +478,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
	struct ipath_qp *qp = to_iqp(ibqp);
	enum ib_qp_state cur_state, new_state;
	unsigned long flags;
	int lastwqe = 0;
	int ret;

	spin_lock_irqsave(&qp->s_lock, flags);
@@ -532,7 +538,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
		break;

	case IB_QPS_ERR:
		ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
		lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
		break;

	default:
@@ -591,6 +597,14 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
	qp->state = new_state;
	spin_unlock_irqrestore(&qp->s_lock, flags);

	if (lastwqe) {
		struct ib_event ev;

		ev.device = qp->ibqp.device;
		ev.element.qp = &qp->ibqp;
		ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
		qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
	}
	ret = 0;
	goto bail;

+11 −1
Original line number Diff line number Diff line
@@ -1497,11 +1497,21 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
{
	unsigned long flags;
	int lastwqe;

	spin_lock_irqsave(&qp->s_lock, flags);
	qp->state = IB_QPS_ERR;
	ipath_error_qp(qp, err);
	lastwqe = ipath_error_qp(qp, err);
	spin_unlock_irqrestore(&qp->s_lock, flags);

	if (lastwqe) {
		struct ib_event ev;

		ev.device = qp->ibqp.device;
		ev.element.qp = &qp->ibqp;
		ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
		qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
	}
}

static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n)
+1 −1
Original line number Diff line number Diff line
@@ -672,7 +672,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,

int ipath_destroy_qp(struct ib_qp *ibqp);

void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err);
int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err);

int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
		    int attr_mask, struct ib_udata *udata);