Pārlūkot izejas kodu

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>
Ralph Campbell 17 gadi atpakaļ
vecāks
revīzija
7ec01ff950
1 mainītis faili ar 6 papildinājumiem un 2 dzēšanām
  1. 6 2
      drivers/infiniband/hw/ipath/ipath_ud.c

+ 6 - 2
drivers/infiniband/hw/ipath/ipath_ud.c

@@ -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)
-		qp->s_cur = 0;
+	next_cur = qp->s_cur + 1;
+	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;