Skip to content

Commit

Permalink
IB/ipath: Fix lost UD send work request
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ralph Campbell authored and Roland Dreier committed Aug 15, 2008
1 parent ffaa5b9 commit 7ec01ff
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions drivers/infiniband/hw/ipath/ipath_ud.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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;

Expand Down

0 comments on commit 7ec01ff

Please sign in to comment.