Blame SOURCES/libbnxt_re_fix_lat_test_failure_in_event_mode.patch

95af3a
commit 0b72e02a1fee3e383fad0aa2e7e5cf8c6a06c6bf
95af3a
Author: Devesh Sharma <devesh.sharma@broadcom.com>
95af3a
Date:   Wed Jan 31 01:28:53 2018 -0500
95af3a
95af3a
    libbnxt_re: Fix lat test failure in event mode
95af3a
    
95af3a
    The application assumes that, when CQ is armed, it gives interrupt
95af3a
    for the new CQEs generated and not for the existing CQEs. This is
95af3a
    in-line with the IB-Spec. However, Broadcom HW generates an interrupt
95af3a
    for any unread CQEs not just new ones. This results in a scenario
95af3a
    where the application is expecting a completion for a SEND operation
95af3a
    but it receives a completion for a prior incoming-send/RQE that was
95af3a
    not yet consumed as per the HW thereby leading to failure.
95af3a
    Workaround this by deferring the ARM-ing of the CQ when invoked in
95af3a
    the notify_cq hook to 'poll_cq' so that the CQ is armed after all
95af3a
    completions are consumed.
95af3a
    
95af3a
    Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
95af3a
    Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
95af3a
    Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
95af3a
95af3a
diff --git a/providers/bnxt_re/main.h b/providers/bnxt_re/main.h
95af3a
index affe24f0..08aa277d 100644
95af3a
--- a/providers/bnxt_re/main.h
95af3a
+++ b/providers/bnxt_re/main.h
95af3a
@@ -76,6 +76,9 @@ struct bnxt_re_cq {
95af3a
 	struct list_head rfhead;
95af3a
 	uint32_t cqe_size;
95af3a
 	uint8_t  phase;
95af3a
+	int deferred_arm_flags;
95af3a
+	bool first_arm;
95af3a
+	bool deferred_arm;
95af3a
 };
95af3a
 
95af3a
 struct bnxt_re_srq {
95af3a
diff --git a/providers/bnxt_re/verbs.c b/providers/bnxt_re/verbs.c
95af3a
index 09ac3335..2e88304c 100644
95af3a
--- a/providers/bnxt_re/verbs.c
95af3a
+++ b/providers/bnxt_re/verbs.c
95af3a
@@ -202,6 +202,7 @@ struct ibv_cq *bnxt_re_create_cq(struct ibv_context *ibvctx, int ncqe,
95af3a
 	cq->phase = resp.phase;
95af3a
 	cq->cqq.tail = resp.tail;
95af3a
 	cq->udpi = &cntx->udpi;
95af3a
+	cq->first_arm = true;
95af3a
 
95af3a
 	list_head_init(&cq->sfhead);
95af3a
 	list_head_init(&cq->rfhead);
95af3a
@@ -654,6 +655,11 @@ int bnxt_re_poll_cq(struct ibv_cq *ibvcq, int nwc, struct ibv_wc *wc)
95af3a
 
95af3a
 	pthread_spin_lock(&cq->cqq.qlock);
95af3a
 	dqed = bnxt_re_poll_one(cq, nwc, wc);
95af3a
+	if (cq->deferred_arm) {
95af3a
+		bnxt_re_ring_cq_arm_db(cq, cq->deferred_arm_flags);
95af3a
+		cq->deferred_arm = false;
95af3a
+		cq->deferred_arm_flags = 0;
95af3a
+	}
95af3a
 	pthread_spin_unlock(&cq->cqq.qlock);
95af3a
 	/* Check if anything is there to flush. */
95af3a
 	pthread_spin_lock(&cntx->fqlock);
95af3a
@@ -718,7 +724,12 @@ int bnxt_re_arm_cq(struct ibv_cq *ibvcq, int flags)
95af3a
 	pthread_spin_lock(&cq->cqq.qlock);
95af3a
 	flags = !flags ? BNXT_RE_QUE_TYPE_CQ_ARMALL :
95af3a
 			 BNXT_RE_QUE_TYPE_CQ_ARMSE;
95af3a
-	bnxt_re_ring_cq_arm_db(cq, flags);
95af3a
+	if (cq->first_arm) {
95af3a
+		bnxt_re_ring_cq_arm_db(cq, flags);
95af3a
+		cq->first_arm = false;
95af3a
+	}
95af3a
+	cq->deferred_arm = true;
95af3a
+	cq->deferred_arm_flags = flags;
95af3a
 	pthread_spin_unlock(&cq->cqq.qlock);
95af3a
 
95af3a
 	return 0;