IB/ipath: Fix lost UD send work request
If a UD QP has some work requests queued to be sent by the DMA engine followed by a local loopback work request, we have to wait for the previous work requests to finish or the completion for the local loopback work request would be generated out of order. The problem was that the work request queue pointer was already updated so that the request would not be processed when the DMA queue drained. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
ffaa5b984a
commit
7ec01ff950
|
@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||||
u16 lrh0;
|
u16 lrh0;
|
||||||
u16 lid;
|
u16 lid;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int next_cur;
|
||||||
|
|
||||||
spin_lock_irqsave(&qp->s_lock, flags);
|
spin_lock_irqsave(&qp->s_lock, flags);
|
||||||
|
|
||||||
|
@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
wqe = get_swqe_ptr(qp, qp->s_cur);
|
wqe = get_swqe_ptr(qp, qp->s_cur);
|
||||||
if (++qp->s_cur >= qp->s_size)
|
next_cur = qp->s_cur + 1;
|
||||||
qp->s_cur = 0;
|
if (next_cur >= qp->s_size)
|
||||||
|
next_cur = 0;
|
||||||
|
|
||||||
/* Construct the header. */
|
/* Construct the header. */
|
||||||
ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
|
ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
|
||||||
|
@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||||
qp->s_flags |= IPATH_S_WAIT_DMA;
|
qp->s_flags |= IPATH_S_WAIT_DMA;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
qp->s_cur = next_cur;
|
||||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||||
ipath_ud_loopback(qp, wqe);
|
ipath_ud_loopback(qp, wqe);
|
||||||
spin_lock_irqsave(&qp->s_lock, flags);
|
spin_lock_irqsave(&qp->s_lock, flags);
|
||||||
|
@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qp->s_cur = next_cur;
|
||||||
extra_bytes = -wqe->length & 3;
|
extra_bytes = -wqe->length & 3;
|
||||||
nwords = (wqe->length + extra_bytes) >> 2;
|
nwords = (wqe->length + extra_bytes) >> 2;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue