Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Apr 2019 19:37:16 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r346921 - stable/11/sys/dev/cxgbe
Message-ID:  <201904291937.x3TJbGnm078315@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Mon Apr 29 19:37:16 2019
New Revision: 346921
URL: https://svnweb.freebsd.org/changeset/base/346921

Log:
  MFC r339626:
  
  cxgbe(4): Use automatic cidx updates with ofld and ctrl queues.
  
  The bits that explicitly request cidx updates do not work reliably with
  all possible WRs that can be sent over the queue.  The F_FW_WR_EQUIQ
  requests that still remain may also have to be replaced with explicit
  credit flush WRs in the future.
  
  Sponsored by:	Chelsio Communications

Modified:
  stable/11/sys/dev/cxgbe/t4_sge.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- stable/11/sys/dev/cxgbe/t4_sge.c	Mon Apr 29 19:36:46 2019	(r346920)
+++ stable/11/sys/dev/cxgbe/t4_sge.c	Mon Apr 29 19:37:16 2019	(r346921)
@@ -2044,12 +2044,13 @@ drain_wrq_wr_list(struct adapter *sc, struct sge_wrq *
 
 		if (available < eq->sidx / 4 &&
 		    atomic_cmpset_int(&eq->equiq, 0, 1)) {
+				/*
+				 * XXX: This is not 100% reliable with some
+				 * types of WRs.  But this is a very unusual
+				 * situation for an ofld/ctrl queue anyway.
+				 */
 			dst->equiq_to_len16 |= htobe32(F_FW_WR_EQUIQ |
 			    F_FW_WR_EQUEQ);
-			eq->equeqidx = eq->pidx;
-		} else if (IDXDIFF(eq->pidx, eq->equeqidx, eq->sidx) >= 32) {
-			dst->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ);
-			eq->equeqidx = eq->pidx;
 		}
 
 		dbdiff += n;
@@ -2476,12 +2477,13 @@ commit_wrq_wr(struct sge_wrq *wrq, void *w, struct wrq
 			available = IDXDIFF(eq->cidx, eq->pidx, eq->sidx) - 1;
 			if (available < eq->sidx / 4 &&
 			    atomic_cmpset_int(&eq->equiq, 0, 1)) {
+				/*
+				 * XXX: This is not 100% reliable with some
+				 * types of WRs.  But this is a very unusual
+				 * situation for an ofld/ctrl queue anyway.
+				 */
 				dst->equiq_to_len16 |= htobe32(F_FW_WR_EQUIQ |
 				    F_FW_WR_EQUEQ);
-				eq->equeqidx = pidx;
-			} else if (IDXDIFF(eq->pidx, eq->equeqidx, eq->sidx) >= 32) {
-				dst->equiq_to_len16 |= htobe32(F_FW_WR_EQUEQ);
-				eq->equeqidx = pidx;
 			}
 
 			ring_eq_db(wrq->adapter, eq, ndesc);
@@ -3404,6 +3406,23 @@ free_nm_txq(struct vi_info *vi, struct sge_nm_txq *nm_
 }
 #endif
 
+/*
+ * Returns a reasonable automatic cidx flush threshold for a given queue size.
+ */
+static u_int
+qsize_to_fthresh(int qsize)
+{
+	u_int fthresh;
+
+	while (!powerof2(qsize))
+		qsize++;
+	fthresh = ilog2(qsize);
+	if (fthresh > X_CIDXFLUSHTHRESH_128)
+		fthresh = X_CIDXFLUSHTHRESH_128;
+
+	return (fthresh);
+}
+
 static int
 ctrl_eq_alloc(struct adapter *sc, struct sge_eq *eq)
 {
@@ -3427,7 +3446,7 @@ ctrl_eq_alloc(struct adapter *sc, struct sge_eq *eq)
 	c.dcaen_to_eqsize =
 	    htobe32(V_FW_EQ_CTRL_CMD_FBMIN(X_FETCHBURSTMIN_64B) |
 		V_FW_EQ_CTRL_CMD_FBMAX(X_FETCHBURSTMAX_512B) |
-		V_FW_EQ_CTRL_CMD_CIDXFTHRESH(X_CIDXFLUSHTHRESH_32) |
+		V_FW_EQ_CTRL_CMD_CIDXFTHRESH(qsize_to_fthresh(qsize)) |
 		V_FW_EQ_CTRL_CMD_EQSIZE(qsize));
 	c.eqaddr = htobe64(eq->ba);
 
@@ -3509,12 +3528,13 @@ ofld_eq_alloc(struct adapter *sc, struct vi_info *vi, 
 	c.alloc_to_len16 = htonl(F_FW_EQ_OFLD_CMD_ALLOC |
 	    F_FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c));
 	c.fetchszm_to_iqid =
-		htonl(V_FW_EQ_OFLD_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) |
+		htonl(V_FW_EQ_OFLD_CMD_HOSTFCMODE(X_HOSTFCMODE_STATUS_PAGE) |
 		    V_FW_EQ_OFLD_CMD_PCIECHN(eq->tx_chan) |
 		    F_FW_EQ_OFLD_CMD_FETCHRO | V_FW_EQ_OFLD_CMD_IQID(eq->iqid));
 	c.dcaen_to_eqsize =
 	    htobe32(V_FW_EQ_OFLD_CMD_FBMIN(X_FETCHBURSTMIN_64B) |
 		V_FW_EQ_OFLD_CMD_FBMAX(X_FETCHBURSTMAX_512B) |
+		V_FW_EQ_OFLD_CMD_CIDXFTHRESH(qsize_to_fthresh(qsize)) |
 		V_FW_EQ_OFLD_CMD_EQSIZE(qsize));
 	c.eqaddr = htobe64(eq->ba);
 
@@ -3552,8 +3572,9 @@ alloc_eq(struct adapter *sc, struct vi_info *vi, struc
 	if (rc)
 		return (rc);
 
-	eq->pidx = eq->cidx = 0;
-	eq->equeqidx = eq->dbidx = 0;
+	eq->pidx = eq->cidx = eq->dbidx = 0;
+	/* Note that equeqidx is not used with sge_wrq (OFLD/CTRL) queues. */
+	eq->equeqidx = 0;
 	eq->doorbells = sc->doorbells;
 
 	switch (eq->flags & EQ_TYPEMASK) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904291937.x3TJbGnm078315>