return -EFAULT;
}
if (unlikely(wh->sq_seq != sq_seq_num)) {
- bool dup_case = (wh->sq_seq - sq_seq_num == sq->entries);
+ bool dup_case = (wh->sq_seq - sq_seq_num == sq->entries);
int log_level = dup_case ? SIF_WCE : SIF_INFO;
sif_log(sdev, log_level,
cq_sw->next_seq = 0;
cq_sw->last_hw_seq = 0;
- /* Make sure we never fill the CQ completely on rev 1-3 - Bug #3657 */
+ /* Make sure we never fill the CQ completely on rev 1-3 - Bug #3657.
+ * bug #4074 - add SIF_SW_RESERVED_DUL_CQE 768 entries to avoid worst case
+ * duplicate completions that can be generated by HW and 1 entry for the
+ * fence completion.
+ */
if (PSIF_REVISION(sdev) <= 3)
- entries++;
+ entries += (SIF_SW_RESERVED_DUL_CQE + SIF_SW_RESERVED_LAST_CQE);
cq->entries = roundup_pow_of_two(entries);
cq->ibcq.cqe = cq->entries;
entries_log2 = order_base_2(cq->entries);
- /* Adjust available cqes on rev 1-3 - Bug #3657 */
+ /* Adjust available cqes on rev 1-3 - Bug #3657 and #4074. */
if (PSIF_REVISION(sdev) <= 3)
- cq->ibcq.cqe--;
+ cq->ibcq.cqe -= (SIF_SW_RESERVED_DUL_CQE + SIF_SW_RESERVED_LAST_CQE);
/* See #2965: 5 bit size_log2 field in cq desc
* but counter is 32 bit. For simplicity to distinguish full from empty
*/
#define SIF_SW_MAX_CQE_LOG2 0x18 /* = 16 MB - tested and should cover most use cases.. */
#define SIF_SW_MAX_CQE (1 << SIF_SW_MAX_CQE_LOG2)
+/* 768 entries for the HW duplicate completions and 1 entry for the fence completion. */
+#define SIF_SW_RESERVED_DUL_CQE (768 + 1)
+#define SIF_SW_RESERVED_LAST_CQE 1
#define SIF_SW_MAX_SQE_LOG2 0xf /* = 32K */
#define SIF_SW_MAX_SQE (1 << SIF_SW_MAX_SQE_LOG2)
*
*/
#define SIF_UVERBS_ABI_MAJOR_VERSION 3
-#define SIF_UVERBS_ABI_MINOR_VERSION 5
+#define SIF_UVERBS_ABI_MINOR_VERSION 6
#define SIF_UVERBS_VERSION(x, y) ((x) << 8 | (y))