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>
此提交包含在:
@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||
u16 lrh0;
|
||||
u16 lid;
|
||||
int ret = 0;
|
||||
int next_cur;
|
||||
|
||||
spin_lock_irqsave(&qp->s_lock, flags);
|
||||
|
||||
@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp)
|
||||
goto bail;
|
||||
|
||||
wqe = get_swqe_ptr(qp, qp->s_cur);
|
||||
if (++qp->s_cur >= qp->s_size)
|
||||
qp->s_cur = 0;
|
||||
next_cur = qp->s_cur + 1;
|
||||
if (next_cur >= qp->s_size)
|
||||
next_cur = 0;
|
||||
|
||||
/* Construct the header. */
|
||||
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;
|
||||
goto bail;
|
||||
}
|
||||
qp->s_cur = next_cur;
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
ipath_ud_loopback(qp, wqe);
|
||||
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;
|
||||
nwords = (wqe->length + extra_bytes) >> 2;
|
||||
|
||||
|
新增問題並參考
封鎖使用者