svn commit: r317041 - head/sys/dev/cxgbe

Navdeep Parhar np at FreeBSD.org
Mon Apr 17 09:00:22 UTC 2017


Author: np
Date: Mon Apr 17 09:00:20 2017
New Revision: 317041
URL: https://svnweb.freebsd.org/changeset/base/317041

Log:
  cxgbe: Add tunables to control the number of LRO entries and the number
  of rx mbufs that should be presorted before LRO.  There is no change in
  default behavior.
  
  MFC after:	1 week
  Sponsored by:	Chelsio Communications

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h	Mon Apr 17 07:27:45 2017	(r317040)
+++ head/sys/dev/cxgbe/adapter.h	Mon Apr 17 09:00:20 2017	(r317041)
@@ -322,6 +322,7 @@ enum {
 	IQ_HAS_FL	= (1 << 1),	/* iq associated with a freelist */
 	IQ_INTR		= (1 << 2),	/* iq takes direct interrupt */
 	IQ_LRO_ENABLED	= (1 << 3),	/* iq is an eth rxq with LRO enabled */
+	IQ_ADJ_CREDIT	= (1 << 4),	/* hw is off by 1 credit for this iq */
 
 	/* iq state */
 	IQS_DISABLED	= 0,

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Mon Apr 17 07:27:45 2017	(r317040)
+++ head/sys/dev/cxgbe/t4_sge.c	Mon Apr 17 09:00:20 2017	(r317041)
@@ -157,6 +157,18 @@ TUNABLE_INT("hw.cxgbe.safest_rx_cluster"
 static int tscale = 1;
 TUNABLE_INT("hw.cxgbe.tscale", &tscale);
 
+/*
+ * Number of LRO entries in the lro_ctrl structure per rx queue.
+ */
+static int lro_entries = TCP_LRO_ENTRIES;
+TUNABLE_INT("hw.cxgbe.lro_entries", &lro_entries);
+
+/*
+ * This enables presorting of frames before they're fed into tcp_lro_rx.
+ */
+static int lro_mbufs = 0;
+TUNABLE_INT("hw.cxgbe.lro_mbufs", &lro_mbufs);
+
 struct txpkts {
 	u_int wr_type;		/* type 0 or type 1 */
 	u_int npkt;		/* # of packets in this work request */
@@ -1380,6 +1392,13 @@ t4_vi_intr(void *arg)
 		t4_intr(irq->rxq);
 }
 
+static inline int
+sort_before_lro(struct lro_ctrl *lro)
+{
+
+	return (lro->lro_mbuf_max != 0);
+}
+
 /*
  * Deals with anything and everything on the given ingress queue.
  */
@@ -1399,6 +1418,7 @@ service_iq(struct sge_iq *iq, int budget
 	STAILQ_HEAD(, sge_iq) iql = STAILQ_HEAD_INITIALIZER(iql);
 #if defined(INET) || defined(INET6)
 	const struct timeval lro_timeout = {0, sc->lro_timeout};
+	struct lro_ctrl *lro = &rxq->lro;
 #endif
 
 	KASSERT(iq->state == IQS_BUSY, ("%s: iq %p not BUSY", __func__, iq));
@@ -1413,6 +1433,23 @@ service_iq(struct sge_iq *iq, int budget
 		fl_hw_cidx = 0;			/* to silence gcc warning */
 	}
 
+#if defined(INET) || defined(INET6)
+	if (iq->flags & IQ_ADJ_CREDIT) {
+		MPASS(sort_before_lro(lro));
+		iq->flags &= ~IQ_ADJ_CREDIT;
+		if ((d->rsp.u.type_gen & F_RSPD_GEN) != iq->gen) {
+			tcp_lro_flush_all(lro);
+			t4_write_reg(sc, sc->sge_gts_reg, V_CIDXINC(1) |
+			    V_INGRESSQID((u32)iq->cntxt_id) |
+			    V_SEINTARM(iq->intr_params));
+			return (0);
+		}
+		ndescs = 1;
+	}
+#else
+	MPASS((iq->flags & IQ_ADJ_CREDIT) == 0);
+#endif
+
 	/*
 	 * We always come back and check the descriptor ring for new indirect
 	 * interrupts and other responses after running a single handler.
@@ -1524,8 +1561,9 @@ service_iq(struct sge_iq *iq, int budget
 
 #if defined(INET) || defined(INET6)
 				if (iq->flags & IQ_LRO_ENABLED &&
+				    !sort_before_lro(lro) &&
 				    sc->lro_timeout != 0) {
-					tcp_lro_flush_inactive(&rxq->lro,
+					tcp_lro_flush_inactive(lro,
 					    &lro_timeout);
 				}
 #endif
@@ -1565,9 +1603,14 @@ process_iql:
 
 #if defined(INET) || defined(INET6)
 	if (iq->flags & IQ_LRO_ENABLED) {
-		struct lro_ctrl *lro = &rxq->lro;
-
-		tcp_lro_flush_all(lro);
+		if (ndescs > 0 && lro->lro_mbuf_count > 8) {
+			MPASS(sort_before_lro(lro));
+			/* hold back one credit and don't flush LRO state */
+			iq->flags |= IQ_ADJ_CREDIT;
+			ndescs--;
+		} else {
+			tcp_lro_flush_all(lro);
+		}
 	}
 #endif
 
@@ -1856,10 +1899,14 @@ t4_eth_rx(struct sge_iq *iq, const struc
 	}
 
 #if defined(INET) || defined(INET6)
-	if (iq->flags & IQ_LRO_ENABLED &&
-	    tcp_lro_rx(lro, m0, 0) == 0) {
-		/* queued for LRO */
-	} else
+	if (iq->flags & IQ_LRO_ENABLED) {
+		if (sort_before_lro(lro)) {
+			tcp_lro_queue_mbuf(lro, m0);
+			return (0); /* queued for sort, then LRO */
+		}
+		if (tcp_lro_rx(lro, m0, 0) == 0)
+			return (0); /* queued for LRO */
+	}
 #endif
 	ifp->if_input(ifp, m0);
 
@@ -3050,10 +3097,10 @@ alloc_rxq(struct vi_info *vi, struct sge
 	FL_UNLOCK(&rxq->fl);
 
 #if defined(INET) || defined(INET6)
-	rc = tcp_lro_init(&rxq->lro);
+	rc = tcp_lro_init_args(&rxq->lro, vi->ifp, lro_entries, lro_mbufs);
 	if (rc != 0)
 		return (rc);
-	rxq->lro.ifp = vi->ifp; /* also indicates LRO init'ed */
+	MPASS(rxq->lro.ifp == vi->ifp);	/* also indicates LRO init'ed */
 
 	if (vi->ifp->if_capenable & IFCAP_LRO)
 		rxq->iq.flags |= IQ_LRO_ENABLED;


More information about the svn-src-head mailing list