|
@@ -191,6 +191,7 @@ static inline void reset_retry_counters(struct rxe_qp *qp)
|
|
|
{
|
|
|
qp->comp.retry_cnt = qp->attr.retry_cnt;
|
|
|
qp->comp.rnr_retry = qp->attr.rnr_retry;
|
|
|
+ qp->comp.started_retry = 0;
|
|
|
}
|
|
|
|
|
|
static inline enum comp_state check_psn(struct rxe_qp *qp,
|
|
@@ -676,6 +677,20 @@ int rxe_completer(void *arg)
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
+ /* if we've started a retry, don't start another
|
|
|
+ * retry sequence, unless this is a timeout.
|
|
|
+ */
|
|
|
+ if (qp->comp.started_retry &&
|
|
|
+ !qp->comp.timeout_retry) {
|
|
|
+ if (pkt) {
|
|
|
+ rxe_drop_ref(pkt->qp);
|
|
|
+ kfree_skb(skb);
|
|
|
+ skb = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
if (qp->comp.retry_cnt > 0) {
|
|
|
if (qp->comp.retry_cnt != 7)
|
|
|
qp->comp.retry_cnt--;
|
|
@@ -692,6 +707,7 @@ int rxe_completer(void *arg)
|
|
|
rxe_counter_inc(rxe,
|
|
|
RXE_CNT_COMP_RETRY);
|
|
|
qp->req.need_retry = 1;
|
|
|
+ qp->comp.started_retry = 1;
|
|
|
rxe_run_task(&qp->req.task, 1);
|
|
|
}
|
|
|
|
|
@@ -701,7 +717,7 @@ int rxe_completer(void *arg)
|
|
|
skb = NULL;
|
|
|
}
|
|
|
|
|
|
- goto exit;
|
|
|
+ goto done;
|
|
|
|
|
|
} else {
|
|
|
rxe_counter_inc(rxe, RXE_CNT_RETRY_EXCEEDED);
|