diff mbox series

[for-next,v2,2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs

Message ID 1723621322-6920-3-git-send-email-selvin.xavier@broadcom.com (mailing list archive)
State Superseded
Headers show
Series RDMA/bnxt_re: Use variable size Work Queue entry for Gen P7 adapters | expand

Commit Message

Selvin Xavier Aug. 14, 2024, 7:42 a.m. UTC
While reporting the completions, SQ Work Queue index is required to
identify the WQE that generated the completions. In variable WQE mode,
FW returns the slot index for Error completions. Driver need to walk
through the shadow queue between the consumer index  and producer index
and matches the slot index returned by FW. If a match is found, the next
index of the shadow queue is the WQE index to be considered for remaining
poll_cq loop.

Signed-off-by: Hongguang Gao <hongguang.gao@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 ++++++++++++++++++++++++++++++++
 drivers/infiniband/hw/bnxt_re/qplib_fp.h | 10 ++++++++
 2 files changed, 50 insertions(+)

Comments

kernel test robot Aug. 18, 2024, 11:04 a.m. UTC | #1
Hi Selvin,

kernel test robot noticed the following build warnings:

[auto build test WARNING on rdma/for-next]
[also build test WARNING on linus/master v6.11-rc3 next-20240816]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Selvin-Xavier/RDMA-bnxt_re-Add-support-for-Variable-WQE-in-Genp7-adapters/20240814-223609
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git for-next
patch link:    https://lore.kernel.org/r/1723621322-6920-3-git-send-email-selvin.xavier%40broadcom.com
patch subject: [PATCH for-next v2 2/4] RDMA/bnxt_re: Get the WQE index from slot index while completing the WQEs
config: sparc64-randconfig-r112-20240818 (https://download.01.org/0day-ci/archive/20240818/202408181809.Sed4EJbs-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 14.1.0
reproduce: (https://download.01.org/0day-ci/archive/20240818/202408181809.Sed4EJbs-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408181809.Sed4EJbs-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/infiniband/hw/bnxt_re/qplib_fp.c:2530:64: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected unsigned int [usertype] cqe_slot @@     got restricted __le16 [usertype] sq_cons_idx @@
   drivers/infiniband/hw/bnxt_re/qplib_fp.c:2530:64: sparse:     expected unsigned int [usertype] cqe_slot
   drivers/infiniband/hw/bnxt_re/qplib_fp.c:2530:64: sparse:     got restricted __le16 [usertype] sq_cons_idx
   drivers/infiniband/hw/bnxt_re/qplib_fp.c: note: in included file (through include/linux/smp.h, include/linux/alloc_tag.h, include/linux/percpu.h, ...):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true

vim +2530 drivers/infiniband/hw/bnxt_re/qplib_fp.c

  2499	
  2500	static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
  2501					     struct cq_req *hwcqe,
  2502					     struct bnxt_qplib_cqe **pcqe, int *budget,
  2503					     u32 cq_cons, struct bnxt_qplib_qp **lib_qp)
  2504	{
  2505		struct bnxt_qplib_swq *swq;
  2506		struct bnxt_qplib_cqe *cqe;
  2507		struct bnxt_qplib_qp *qp;
  2508		struct bnxt_qplib_q *sq;
  2509		u32 cqe_sq_cons;
  2510		int cqe_cons;
  2511		int rc = 0;
  2512	
  2513		qp = (struct bnxt_qplib_qp *)((unsigned long)
  2514					      le64_to_cpu(hwcqe->qp_handle));
  2515		if (!qp) {
  2516			dev_err(&cq->hwq.pdev->dev,
  2517				"FP: Process Req qp is NULL\n");
  2518			return -EINVAL;
  2519		}
  2520		sq = &qp->sq;
  2521	
  2522		cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_sw_wqe;
  2523		if (qp->sq.flushed) {
  2524			dev_dbg(&cq->hwq.pdev->dev,
  2525				"%s: QP in Flush QP = %p\n", __func__, qp);
  2526			goto done;
  2527		}
  2528	
  2529		if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
> 2530			cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
  2531			if (cqe_cons < 0) {
  2532				dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
  2533					__func__, hwcqe->sq_cons_idx);
  2534				goto done;
  2535			}
  2536			cqe_sq_cons = cqe_cons;
  2537			dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
  2538				__func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
  2539		}
  2540	
  2541		/* Require to walk the sq's swq to fabricate CQEs for all previously
  2542		 * signaled SWQEs due to CQE aggregation from the current sq cons
  2543		 * to the cqe_sq_cons
  2544		 */
  2545		cqe = *pcqe;
  2546		while (*budget) {
  2547			if (sq->swq_last == cqe_sq_cons)
  2548				/* Done */
  2549				break;
  2550	
  2551			swq = &sq->swq[sq->swq_last];
  2552			memset(cqe, 0, sizeof(*cqe));
  2553			cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
  2554			cqe->qp_handle = (u64)(unsigned long)qp;
  2555			cqe->src_qp = qp->id;
  2556			cqe->wr_id = swq->wr_id;
  2557			if (cqe->wr_id == BNXT_QPLIB_FENCE_WRID)
  2558				goto skip;
  2559			cqe->type = swq->type;
  2560	
  2561			/* For the last CQE, check for status.  For errors, regardless
  2562			 * of the request being signaled or not, it must complete with
  2563			 * the hwcqe error status
  2564			 */
  2565			if (swq->next_idx == cqe_sq_cons &&
  2566			    hwcqe->status != CQ_REQ_STATUS_OK) {
  2567				cqe->status = hwcqe->status;
  2568				dev_err(&cq->hwq.pdev->dev,
  2569					"FP: CQ Processed Req wr_id[%d] = 0x%llx with status 0x%x\n",
  2570					sq->swq_last, cqe->wr_id, cqe->status);
  2571				cqe++;
  2572				(*budget)--;
  2573				bnxt_qplib_mark_qp_error(qp);
  2574				/* Add qp to flush list of the CQ */
  2575				bnxt_qplib_add_flush_qp(qp);
  2576			} else {
  2577				/* Before we complete, do WA 9060 */
  2578				if (do_wa9060(qp, cq, cq_cons, sq->swq_last,
  2579					      cqe_sq_cons)) {
  2580					*lib_qp = qp;
  2581					goto out;
  2582				}
  2583				if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
  2584					cqe->status = CQ_REQ_STATUS_OK;
  2585					cqe++;
  2586					(*budget)--;
  2587				}
  2588			}
  2589	skip:
  2590			bnxt_qplib_hwq_incr_cons(sq->hwq.max_elements, &sq->hwq.cons,
  2591						 swq->slots, &sq->dbinfo.flags);
  2592			sq->swq_last = swq->next_idx;
  2593			if (sq->single)
  2594				break;
  2595		}
  2596	out:
  2597		*pcqe = cqe;
  2598		if (sq->swq_last != cqe_sq_cons) {
  2599			/* Out of budget */
  2600			rc = -EAGAIN;
  2601			goto done;
  2602		}
  2603		/*
  2604		 * Back to normal completion mode only after it has completed all of
  2605		 * the WC for this CQE
  2606		 */
  2607		sq->single = false;
  2608	done:
  2609		return rc;
  2610	}
  2611
diff mbox series

Patch

diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 0af09e7..b49f49c 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -2471,6 +2471,32 @@  static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
 	return rc;
 }
 
+static int bnxt_qplib_get_cqe_sq_cons(struct bnxt_qplib_q *sq, u32 cqe_slot)
+{
+	struct bnxt_qplib_hwq *sq_hwq;
+	struct bnxt_qplib_swq *swq;
+	int cqe_sq_cons = -1;
+	u32 start, last;
+
+	sq_hwq = &sq->hwq;
+
+	start = sq->swq_start;
+	last = sq->swq_last;
+
+	while (last != start) {
+		swq = &sq->swq[last];
+		if (swq->slot_idx  == cqe_slot) {
+			cqe_sq_cons = swq->next_idx;
+			dev_err(&sq_hwq->pdev->dev, "%s: Found cons wqe = %d slot = %d\n",
+				__func__, cqe_sq_cons, cqe_slot);
+			break;
+		}
+
+		last = swq->next_idx;
+	}
+	return cqe_sq_cons;
+}
+
 static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
 				     struct cq_req *hwcqe,
 				     struct bnxt_qplib_cqe **pcqe, int *budget,
@@ -2481,6 +2507,7 @@  static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
 	struct bnxt_qplib_qp *qp;
 	struct bnxt_qplib_q *sq;
 	u32 cqe_sq_cons;
+	int cqe_cons;
 	int rc = 0;
 
 	qp = (struct bnxt_qplib_qp *)((unsigned long)
@@ -2498,6 +2525,19 @@  static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
 			"%s: QP in Flush QP = %p\n", __func__, qp);
 		goto done;
 	}
+
+	if (__is_err_cqe_for_var_wqe(qp, hwcqe->status)) {
+		cqe_cons = bnxt_qplib_get_cqe_sq_cons(sq, hwcqe->sq_cons_idx);
+		if (cqe_cons < 0) {
+			dev_err(&cq->hwq.pdev->dev, "%s: Wrong SQ cons cqe_slot_indx = %d\n",
+				__func__, hwcqe->sq_cons_idx);
+			goto done;
+		}
+		cqe_sq_cons = cqe_cons;
+		dev_err(&cq->hwq.pdev->dev, "%s: cqe_sq_cons = %d swq_last = %d swq_start = %d\n",
+			__func__, cqe_sq_cons, sq->swq_last, sq->swq_start);
+	}
+
 	/* Require to walk the sq's swq to fabricate CQEs for all previously
 	 * signaled SWQEs due to CQE aggregation from the current sq cons
 	 * to the cqe_sq_cons
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index f54d7a0..2e7a4fd 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -649,4 +649,14 @@  static inline __le64 bnxt_re_update_msn_tbl(u32 st_idx, u32 npsn, u32 start_psn)
 		(((start_psn) << SQ_MSN_SEARCH_START_PSN_SFT) &
 		SQ_MSN_SEARCH_START_PSN_MASK));
 }
+
+static inline bool __is_var_wqe(struct bnxt_qplib_qp *qp)
+{
+	return (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE);
+}
+
+static inline bool __is_err_cqe_for_var_wqe(struct bnxt_qplib_qp *qp, u8 status)
+{
+	return (status != CQ_REQ_STATUS_OK) && __is_var_wqe(qp);
+}
 #endif /* __BNXT_QPLIB_FP_H__ */