IB/qib: Insure last cursor is updated prior to complete
This patch is a prerequisite for adding a separate lock for post send. The timing of updating s_last needs to be before returning any send completion to avoid a race between a poll cq seeing a completion and the post send checking for a full queue. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
6c2ab0b857
commit
ee84541ad1
|
@ -1008,10 +1008,18 @@ void qib_rc_send_complete(struct rvt_qp *qp, struct qib_ib_header *hdr)
|
||||||
start_timer(qp);
|
start_timer(qp);
|
||||||
|
|
||||||
while (qp->s_last != qp->s_acked) {
|
while (qp->s_last != qp->s_acked) {
|
||||||
|
u32 s_last;
|
||||||
|
|
||||||
wqe = rvt_get_swqe_ptr(qp, qp->s_last);
|
wqe = rvt_get_swqe_ptr(qp, qp->s_last);
|
||||||
if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) >= 0 &&
|
if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) >= 0 &&
|
||||||
qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0)
|
qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0)
|
||||||
break;
|
break;
|
||||||
|
s_last = qp->s_last;
|
||||||
|
if (++s_last >= qp->s_size)
|
||||||
|
s_last = 0;
|
||||||
|
qp->s_last = s_last;
|
||||||
|
/* see post_send() */
|
||||||
|
barrier();
|
||||||
for (i = 0; i < wqe->wr.num_sge; i++) {
|
for (i = 0; i < wqe->wr.num_sge; i++) {
|
||||||
struct rvt_sge *sge = &wqe->sg_list[i];
|
struct rvt_sge *sge = &wqe->sg_list[i];
|
||||||
|
|
||||||
|
@ -1028,8 +1036,6 @@ void qib_rc_send_complete(struct rvt_qp *qp, struct qib_ib_header *hdr)
|
||||||
wc.qp = &qp->ibqp;
|
wc.qp = &qp->ibqp;
|
||||||
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
|
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
|
||||||
}
|
}
|
||||||
if (++qp->s_last >= qp->s_size)
|
|
||||||
qp->s_last = 0;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If we were waiting for sends to complete before resending,
|
* If we were waiting for sends to complete before resending,
|
||||||
|
@ -1068,11 +1074,19 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
|
||||||
*/
|
*/
|
||||||
if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) < 0 ||
|
if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) < 0 ||
|
||||||
qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) > 0) {
|
qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) > 0) {
|
||||||
|
u32 s_last;
|
||||||
|
|
||||||
for (i = 0; i < wqe->wr.num_sge; i++) {
|
for (i = 0; i < wqe->wr.num_sge; i++) {
|
||||||
struct rvt_sge *sge = &wqe->sg_list[i];
|
struct rvt_sge *sge = &wqe->sg_list[i];
|
||||||
|
|
||||||
rvt_put_mr(sge->mr);
|
rvt_put_mr(sge->mr);
|
||||||
}
|
}
|
||||||
|
s_last = qp->s_last;
|
||||||
|
if (++s_last >= qp->s_size)
|
||||||
|
s_last = 0;
|
||||||
|
qp->s_last = s_last;
|
||||||
|
/* see post_send() */
|
||||||
|
barrier();
|
||||||
/* Post a send completion queue entry if requested. */
|
/* Post a send completion queue entry if requested. */
|
||||||
if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
|
if (!(qp->s_flags & RVT_S_SIGNAL_REQ_WR) ||
|
||||||
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
||||||
|
@ -1084,8 +1098,6 @@ static struct rvt_swqe *do_rc_completion(struct rvt_qp *qp,
|
||||||
wc.qp = &qp->ibqp;
|
wc.qp = &qp->ibqp;
|
||||||
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
|
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.send_cq), &wc, 0);
|
||||||
}
|
}
|
||||||
if (++qp->s_last >= qp->s_size)
|
|
||||||
qp->s_last = 0;
|
|
||||||
} else
|
} else
|
||||||
this_cpu_inc(*ibp->rvp.rc_delayed_comp);
|
this_cpu_inc(*ibp->rvp.rc_delayed_comp);
|
||||||
|
|
||||||
|
|
|
@ -795,6 +795,13 @@ void qib_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
|
||||||
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_OR_FLUSH_SEND))
|
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_OR_FLUSH_SEND))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
last = qp->s_last;
|
||||||
|
old_last = last;
|
||||||
|
if (++last >= qp->s_size)
|
||||||
|
last = 0;
|
||||||
|
qp->s_last = last;
|
||||||
|
/* See post_send() */
|
||||||
|
barrier();
|
||||||
for (i = 0; i < wqe->wr.num_sge; i++) {
|
for (i = 0; i < wqe->wr.num_sge; i++) {
|
||||||
struct rvt_sge *sge = &wqe->sg_list[i];
|
struct rvt_sge *sge = &wqe->sg_list[i];
|
||||||
|
|
||||||
|
@ -822,11 +829,6 @@ void qib_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
|
||||||
status != IB_WC_SUCCESS);
|
status != IB_WC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
last = qp->s_last;
|
|
||||||
old_last = last;
|
|
||||||
if (++last >= qp->s_size)
|
|
||||||
last = 0;
|
|
||||||
qp->s_last = last;
|
|
||||||
if (qp->s_acked == old_last)
|
if (qp->s_acked == old_last)
|
||||||
qp->s_acked = last;
|
qp->s_acked = last;
|
||||||
if (qp->s_cur == old_last)
|
if (qp->s_cur == old_last)
|
||||||
|
|
Loading…
Reference in New Issue