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-all
mailing list